이런 종류의 일이 BlockingCollection<T>
이 System.Collections.Concurrent
에 정의하여 아주 쉽게 할 수 있습니다 :
여기 개념에 대한 좋은 기사입니다.
BlockingCollection<LogRecord> LogQueue = new BlockingCollection<LogRecord>();
각 생산자가 큐에 항목을 추가합니다 :
while (!Shutdown)
{
LogRecord rec = CreateLogRecord(); // however that's done
LogQueue.Add(rec);
}
그리고 소비자가 비슷한 수행합니다
모든 스레드가 액세스 할 수 있도록
기본적으로, 당신은 당신의 대기열을 생성
while (!Shutdown)
{
LogRecord rec = LogQueue.Take();
// process the record
}
기본적으로 BlockingCollection
은 ConcurrentQueue<T>
을 사용합니다. 그는 가게를 후원한다. ConcurrentQueue
은 스레드 동기화를 처리하고 BlockingCollection
은 항목을 가져 오는 동안 대기 중이 지 않은 대기를 수행합니다. 즉, 대기열에 항목이없는 경우 소비자가 Take
이라고 호출하면 항목을 사용할 수있을 때까지 대기 중이 지 않은 시간 (잠자기/회전 없음)을 수행합니다.
아마도 Onsumer가 추가 조건 인 while (! Shutdown || LogQueue.())을 얻는 것이 유용 할 수 있습니다. C#으로 표현됨).또는 LogQueue에 중지 할 수있는 방법이있는 경우에만 사용하십시오. –
glglgl
생산자가 'CompleteAdding'을 호출 할 수 있습니다. 추가를 위해 컬렉션 완료를 표시합니다 (즉, 더 이상 항목을 추가 할 수 없음). 그러면 소비자는'while (LogQueue.TryTake (out rec, Timeout.Infinite)) '을 사용할 수 있습니다. 이는 콜렉션을 비우고 종료한다는 것을 의미합니다. 'TryTake'는 콜렉션이 추가를 위해 완료되고 큐가 비어 있으면'False'를 리턴합니다. –
@JimMischel 소비자가 항목을 대기열에서 제외하고 일부 처리를 수행 한 후 호출 프로세스에 결과를 어떻게 반환 할 수 있습니까? – gdp