16 November 2017

blocking collection in .NET to implement easy concurrent queuing

In the last post I talked about using ConcurrentQueue to implement thread-safe queuing. In this blog post, you will learn about BlockingCollecton which makes it further easier to implement thread-safe queuing.

While reading items from the queue, we usually use while loop to keep reading messages. Now let's look at such a queuing example with ConcurrentQueue.

ConcurrentQueue<Message> queue = new ConcurrentQueue<Message>();
while (!cancelled)
   {
     Message item = null;
     if (queue.TryDequeue(out item))
     {

      // Logic to process the item
      // goes here.
     }

   }

The while loop keeps trying to read the message until its canceled.The thread running the loop will be consuming CPU all the time, even if there are no messages, which is not definitely a good thing.

To reduce CPU overhead with while loop logic to dequeuing the messages, we can take advantage of BlockingCollection introduced in .NET 4.0

What is BlockingCollection

  • BlockingCollection is from "System.Collection.Concurrent" namespace.
  • BlokcingCollection is thread-safe collection.
  • Use BlockingCollection class GetConsumingEnumerable() method to get the IEnumerable. You can use foreach loop around GetConsumingEnumerable() method.This for-each loop will iterate in a loop as long as items are present in it. If not GetConsumingEnumerable will get blocked until an item added to it. That is reason its called BlockingCollection.
  • By default BlockingCollection acts as a ConcurrentQueue i.e., thread-safe, FIFO collection.
  • Similar to Queue, you can keep adding items to BlockingCollecton from mutiple threads. In another thread you keep removing the items via GetConsumingEnumerable() method.

Code using BlockingCollection

BlockingCollection<Message> collection
new BlockingCollection<Message>();

// If not items in blocking collection, 
// the call will get blocked here
foreach(Message message in 
           collection.GetConsumingEnumerable())
 {
                
 }

No comments:

Post a Comment