I'm trying to implement a packet producer-consumer behavior by using a BlockingCollection, but I am having trouble understanding the documentation on it. From what I can tell, since apparently there is no guarantee that I can remove anything at all, the system would be too slow to be useful for performance-critical things like receiving and processing packets. The reason I need this is because the thread that receives packets is not the same thread that processes them. Am I missing something, or do I need to take another approach?
Example Code:
public BlockingCollection<byte[]> unprocessedPackets = new BlockingCollection<byte[]>();
public void Producer()
{
...Recieve packets...
unprocessedPackets.Add(packet);
}
public void Consumer(){
while(true)
{
byte[] packet = unprocessedPackets.Take();
...If i took something, process it.
}
}
That's how
BlockingCollection<T>
works. If and when taking an element from the collection blocks, it's because there's nothing to take. The only "slowness" is in the I/O producing items for the collection.Note that you can pass a timeout value to the
TryTake()
method, which will cause it to wait that length of time before giving up. But if you use theTryTake(out T item)
overload (i.e. the one without a timeout), it will return immediately if there's nothing to take.More typical would be a consumer thread that does nothing but retrieve items for processing. In this case, the
Take()
method or theGetConsumingEnumerable()
method are more appropriate. Both will block indefinitely until there's an item available to take. I prefer the latter; it provides a very nice, usable mechanism both for consuming the collection, and for terminating the consumer when you know there's nothing left (i.e. theCompleteAdding()
method is called by the producing code).