I've reused the example producer consumer queue from the C# in a Nutshell book of Albahari (http://www.albahari.com/threading/part5.aspx#_BlockingCollectionT) and a colleague remarked: "Why isn't the Dispose called on the BlockingCollection in the Dispose of the collection?"
I couldn't find an answer and the only reason I can come up with is that execution of the remaining workload of the queue wouldn't be processed. However, when I'm disposing the queue, why wouldn't it stop processing?
Besides the "Why you shouldn't Dispose the BlockingCollection?" I've got also a second question "Does it harm if you don't dispose a BlockingCollection?". I suppose when you are spawning/disposing a lot of producer consumer queues it gives problems (not that I want that but just for the cause of knowing).
According to What does BlockingCollection.Dispose actually do? BlockingCollection contains two wait handles (obviously) so not calling Dispose will give you some problems. Thanks ken2k for pointing this out.
The code I'm talking about:
public class PCQueue : IDisposable
{
BlockingCollection<Action> _taskQ = new BlockingCollection<Action>();
public PCQueue (int workerCount)
{
// Create and start a separate Task for each consumer:
for (int i = 0; i < workerCount; i++)
Task.Factory.StartNew (Consume);
}
public void Dispose() { _taskQ.CompleteAdding(); }
public void EnqueueTask (Action action) { _taskQ.Add (action); }
void Consume()
{
// This sequence that we’re enumerating will block when no elements
// are available and will end when CompleteAdding is called.
foreach (Action action in _taskQ.GetConsumingEnumerable())
action(); // Perform task.
}
}