This kind of thing is very easy to do using the BlockingCollection<T>
defined in System.Collections.Concurrent
.
Basically, you create your queue so that all threads can access it:
BlockingCollection<LogRecord> LogQueue = new BlockingCollection<LogRecord>();
Each producer adds items to the queue:
while (!Shutdown)
{
LogRecord rec = CreateLogRecord(); // however that's done
LogQueue.Add(rec);
}
And the consumer does something similar:
while (!Shutdown)
{
LogRecord rec = LogQueue.Take();
// process the record
}
By default, BlockingCollection
uses a ConcurrentQueue<T>
as the backing store. The ConcurrentQueue
takes care of thread synchronization and, and the BlockingCollection
does a non-busy wait when trying to take an item. That is, if the consumer calls Take
when there are no items in the queue, it does a non-busy wait (no sleeping/spinning) until an item is available.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…