我有一个C#4.0应用程序,其中包含“高优先级”和“低优先级”队列:
BlockingCollection highPriority = new BlockingCollection(1000); BlockingCollection lowPriority = new BlockingCollection(1000);
在lowPriority中生成的任何数据之前,应先消耗highPriority中生成的任何数据。这里的扭曲是可以随时向两个队列中的任何一个生成数据。因此,在我消耗了highPriority中的所有数据之后,我将使用可能位于lowPriority中的任何数据。如果在我使用lowPriority中的数据时在highPriority中生成新数据,我想完成使用lowPriority中的当前项,然后切换回并处理highPriority中的数据。
有人建议使用算法来帮助解决这个问题吗?伪代码很好。非常感谢。
答案 0 :(得分:3)
这个怎么样:
while(true)
{
workitem = highQueue.dequeue();
if(workitem == null)
workitem = lowQueueu.dequeue()
process(workitem)
}
答案 1 :(得分:1)
如果可以的话,你可以将它包装成一个对象,正如@Kevin Brock建议的那样,让对象实现IProducerConsumerCollection
。否则,调用TryDequeue
的代码将执行繁忙的等待循环。也就是说,有两个队列,你必须写一些类似的东西:
WorkItem item = null;
do
{
if (!hpQueue.TryDequeue(out item))
{
lpQueue.TryDequeue(out item);
}
while (item != null);
如果你使用自己的班级,那么你可以使用事件(EventWaitHandle
等)来防止忙碌的等待。
事实上,使用优先级队列可能会更好。将优先级队列设置为线程安全并实现IProducerConsumerCollection
非常容易,然后您可以将其与BlockingCollection
一起使用。一个好的起点是Julian Bucknall的Priority Queue in C#。
答案 2 :(得分:1)
我会用一个优先级队列来做这件事。这将允许您稍后添加第三优先级,只需很少的代码更改。
我在使用lockFree-SkipList之前编写了一个,但是这是一个使用普通跳过列表的项目(http://www.codeproject.com/KB/recipes/PriorityQueueSkipList.aspx)。我使用了一个跳过列表,因为它们在并发下很好地执行,并且实现起来非常简单(减去无锁版本)。
我还在CodePlex上看到了一个使用红黑树的优先级队列,但我现在找不到它。 更新:我想到的优先级队列实现是NGenerics项目的一部分:http://code.google.com/p/ngenerics/