Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm for .NET consumer thread processing of two queues (based on priority)

I have a C# 4.0 app with "high priority" and "low priority" queues implemented as such:

BlockingCollection highPriority = new BlockingCollection(1000); BlockingCollection lowPriority = new BlockingCollection(1000);

Any data produced in highPriority should be consumed before any data produced in lowPriority. The twist here is that data may be produced to either of the two queues at any time. So after I've consumed all of the data in highPriority, I will then being consuming any data that might be in lowPriority. If new data is produced in highPriority while I'm consuming data in lowPriority, I want to finish consuming the current item in lowPriority and then switch back and process the data in highPriority.

Can anyone suggest an algorithm to help with this? Pseudo code is fine. Thanks very much.

like image 679
bmt22033 Avatar asked Apr 01 '11 16:04

bmt22033


People also ask

Which algorithm make the use of priority queues?

Dijkstra's Shortest Path Algorithm using priority queue: When the graph is stored in the form of adjacency list or matrix, priority queue can be used to extract minimum efficiently when implementing Dijkstra's algorithm.

Which Datastructure is best suited for priority queue?

Priority queue can be implemented using an array, a linked list, a heap data structure, or a binary search tree. Among these data structures, heap data structure provides an efficient implementation of priority queues. Hence, we will be using the heap data structure to implement the priority queue in this tutorial.

Is priority queue thread safe C#?

No. Keep your eye on the big picture, the point of PriorityQueue is iteration. You get the elements back in priority order. Iteration is never thread-safe.

What is multithreaded priority queue?

A computer science concept that is widely used in both non-concurrent and concurrent programming is queuing. A queue is an abstract data structure that is a collection of different elements maintained in a specific order; these elements can be the other objects in a program.


2 Answers

How about this:

while(true)
{
    workitem = highQueue.dequeue();

    if(workitem == null)
        workitem = lowQueueu.dequeue()

    process(workitem)
}
like image 126
Carra Avatar answered Sep 25 '22 02:09

Carra


You'll want to wrap this into a single object if you can, as @Kevin Brock suggested, and have that object implement IProducerConsumerCollection. Otherwise your code that calls TryDequeue will have do do a busy wait loop. That is, with two queues, you have to write something like:

WorkItem item = null;
do
{
    if (!hpQueue.TryDequeue(out item))
    {
        lpQueue.TryDequeue(out item);
    }
while (item != null);

If you use your own class, then you can use events (EventWaitHandle, etc.) to prevent the busy waiting.

In truth, you'd probably be better off using a priority queue. It would be pretty easy to make a priority queue thread-safe and implement IProducerConsumerCollection, and then you can use it with BlockingCollection. A good place to start would be Julian Bucknall's Priority Queue in C#.

like image 33
Jim Mischel Avatar answered Sep 23 '22 02:09

Jim Mischel