January 02, 2015

Observable Concurrent Queue

ConcurrentQueue

I was working with the classic ConcurrentQueue in .Net, It’s a good practice to schedule tasks execution asynchronously, however, getting notified when my ConcurrentQueue content is changed was the problem! How can i know if an element has been enqueued, peeked or dequeued? Also how can i be notified when the queue is empty after last element has been dequeued?

To solve the problem of notification, i’ve developed my custom ConcurrentQueue named ObservableConcurrentQueue inherit from System.Collections.Concurrent.ConcurrentQueue to raise events once the content is changed.

If you are not familiar with the ConcurrentQueue, Please read more about it on MSDN

Syntax & Example:

var observableConcurrentQueue = new ObservableConcurrentQueue<int>();
observableConcurrentQueue.ContentChanged += OnObservableConcurrentQueueContentChanged;

The handleMethod ContentChanged event looks as the follwoing:

private static void OnObservableConcurrentQueueContentChanged(
            object sender, 
            NotifyConcurrentQueueChangedEventArgs<int> args)
        {
            if (args.Action == NotifyConcurrentQueueChangedAction.Enqueue)
            {
                Console.BackgroundColor = ConsoleColor.DarkGreen;
                Console.WriteLine("New Item added: {0}", args.ChangedItem);
            }

            if (args.Action == NotifyConcurrentQueueChangedAction.Dequeue)
            {
                Console.BackgroundColor = ConsoleColor.Red;
                Console.WriteLine("New Item deleted: {0}", args.ChangedItem);
            }

            if (args.Action == NotifyConcurrentQueueChangedAction.Peek)
            {
                Console.BackgroundColor = ConsoleColor.DarkBlue;
                Console.WriteLine("Item peeked: {0}", args.ChangedItem);
            }

            if (args.Action == NotifyConcurrentQueueChangedAction.Empty)
            {
                Console.BackgroundColor = ConsoleColor.White;
                Console.ForegroundColor = ConsoleColor.Blue;
                Console.WriteLine("Queue is empty");
            }

            Console.ResetColor();
        }

Then, Once the handler is defined, we can start adding, deleting or getting elements from the concurrentQueue, and after each operation an event will be raised and handled by the method above.

Event Args:

The EventArgs object sent by the event contains 2 properties:

NotifyConcurrentQueueChangedAction

  • Enqueue: If a new item has been enqueued.
  • Dequeue: an item has been dequeued.
  • Peek: an item has been peeked.
  • Empty: The last element in the queue has been dequeued and the queue is empty.

T ChangedItem

The item which the changes applied on. can be null if the notification action is NotifyConcurrentQueueChangedAction.Empty.

Download

PM> Install-Package ObservableConcurrentQueue

Fork me on GitHub