예, 물론 producer-consumer model의 변형입니다.
여기에 Thread
및 AutoResetEvent
과 같은 몇 가지 기본 구성 블록을 사용할 수 있습니다. 은 "프로듀서는"파일 (? 어쩌면 당신이 대신 메모리 버퍼를 사용할 수 있습니다)에 로그 및 게시물을에서 라인을 읽고 다음을 읽고 다른 스레드를 신호 :
AutoResetEvent consumerEvent = new AutoResetEvent(false);
AutoResetEvent producerEvent = new AutoResetEvent(false);
// producer code
while(/* lines still available */)
{
// read 500 lines
// write to shared file
consumerEvent.Set(); // signal consumer thread
producerEvent.WaitOne(); // wait to be signaled to continue
}
그리고 소비자 코드를 :
while(/* termination not received */)
{
consumerEvent.WaitOne(); // wait for the producer to finish
// read lines from file and put them in the grid
producerEvent.Set(); // allow producer to read more logs
}
이렇게하면 파일을 읽는 소비자와 더 많은 로그를 읽고 다음 배치를 준비하는 프로듀서간에 어느 정도의 병렬 처리가 허용됩니다.
제작자가 로그를 끝내면 파일에 특수 종료 메시지를 넣어 소비자가 정상적으로 종료되었음을 알릴 수 있습니다.
이것은 하나의 전략이며 꽤 낮은 수준이며 오류가 발생하기 쉽습니다. 공유 파일을 완전히 건너 뛸 수 있으며 BlockingCollection 형태로 메모리 내 버퍼를 사용할 수 있습니다.
텍스트의 일부 라인을 유지하기 위해
ProducerTask
클래스를 정의 :이 작업은 한 번에 500 선을 개최한다
class ProducerTask
{
public String[] Lines { get; set; }
}
. 다음과 같이
그런 Task
및 BlockingCollection
(.NET 4.0 이상) 사용
BlockingCollection<ProducerTask> buffer = new BlockingCollection<ProducerTask>(1);
// producer task
while(/* lines still available */)
{
// read 500 lines
ProducerTask p = new ProducerTask();
buffer.Add(p); // this will block until the consumer takes the previous task
}
// consumer task
while(/* termination not received */)
{
ProducerTask p = buffer.Take(); // blocks if no task is available
// put the lines in the grid
}
훨씬 더 간단하고 우아한.
감사합니다. 이것은 내가 찾고있는 것입니다. 한 번에 읽을 수있는 500 줄은 가변적이기 때문에 메모리 내 버퍼를 사용할 수 있다고 생각하지 않습니다. 어떤 숫자라도 될 수 있습니다. 게다가, 응용 프로그램이하는 다른 것들이 있기 때문에 나는 많은 양의 데이터를 메모리에 보유하고 싶지 않습니다. – Albert