What are the differences between ConcurrentQueue and BlockingCollection in .Net?

What are the differences between ConcurrentQueue and BlockingCollection in .Net?

Why BlockingCollection is best for producer-consumer operation when it can be done through ConcurrentQueue? Do I have to improve anything in the following code?

MessageSlotMachineGameStartOrAndStatusUpdate msg;

while (!aCancellationToken.IsCancellationRequested)
{
    try
    {
        this.isStillConsumingMsg = true;
        Boolean takeResult = this.msgQueue.TryTake(out msg, this.msgConsumeTimeOut, aCancellationToken);
        if (takeResult)
        {
            if (msg != null)
            {
                this.ProcessMessage(msg);
            }
        }
        else
        {
            break;
        }
    }
    catch (OperationCanceledException err)
    {
        EngineManager.AddExceptionLog(err, "Signal Operation Canceled");
    }
    catch (Exception err)
    {
        EngineManager.AddExceptionLog(err, "Signal exception");
    }
    finally
    {
        this.isStillConsumingMsg = false;
    }
}

Solution 1:

BlockingCollection has a Take method that would block the consumer if there is nothing to take, and wait for a producer side to provide an item. ConcurrentQueue lacks such method - if it is empty, the consumer would need to handle the wait, and the producer would need to provide a non-empty notification.

Solution 2:

The BlockingCollection is a wrapper for concurrent collections, and the default wrapped collection IS a ConcurrentQueue ;-)

From Microsoft BlockingCollection:

When you create a BlockingCollection object, you can specify not only the bounded capacity but also the type of collection to use. For example, you could specify a ConcurrentQueue object for first in, first out (FIFO) behavior, or a ConcurrentStack object for last in, first out (LIFO) behavior. You can use any collection class that implements the IProducerConsumerCollection interface. The default collection type for BlockingCollection is ConcurrentQueue.

The BlockingCollection has a Take() blocking method (hence the name), but it also has a very interesting GetConsumingEnumerable() method which allows you to loop indefinitely : the code will enter the loop inside code only when something is added to collection. See albahari.com excellent online ebook about Threading.

Here is the code sample from this website:

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.
  }
}