【问题标题】:Algorithm for .NET consumer thread processing of two queues (based on priority).NET消费者线程处理两个队列的算法(基于优先级)
【发布时间】:2011-04-01 16:56:42
【问题描述】:

我有一个具有“高优先级”和“低优先级”队列的 C# 4.0 应用程序:

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

highPriority 中产生的任何数据都应该在 lowPriority 中产生的任何数据之前被使用。这里的转折是数据可以随时生成到两个队列中的任何一个。因此,在我使用 highPriority 中的所有数据之后,我将使用可能处于 lowPriority 的任何数据。如果在我消费lowPriority数据的时候highPriority产生了新数据,我想在lowPriority消费完当前项,然后切换回highPriority处理数据。

谁能建议一种算法来帮助解决这个问题?伪代码很好。非常感谢。

【问题讨论】:

    标签: .net algorithm queue producer-consumer


    【解决方案1】:

    这个怎么样:

    while(true)
    {
        workitem = highQueue.dequeue();
    
        if(workitem == null)
            workitem = lowQueueu.dequeue()
    
        process(workitem)
    }
    

    【讨论】:

    • 如果您需要将其提供给其他客户端类,我喜欢将其抽象出来 - 只需创建自己的 IProducerConsumerCollection 类,其中包含这两者(高优先级和低优先级),然后返回给客户端将BlockingCollection 的实例归类,并由该特殊的IProducerConsunmerCollection 支持。然后,您的自定义类可以提供 Carra 内部解决方案的可用对象。
    • 一个有趣的想法,但是您的代码忽略了一些基本问题,例如当两个队列都为空时会发生什么。此外,您的循环基本上是一个忙碌的等待,它不断检查项目,而不是使用某种等待句柄。我不会推荐这个解决方案。
    • 简化了。我通常会添加一个 if(workitem != null) process(workitem) else Thread.Sleep(100) 或类似的东西。
    • 感谢您的建议!
    【解决方案2】:

    如@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#

    【讨论】:

      【解决方案3】:

      我会用一个优先级队列来做到这一点。这将允许您稍后添加第三个优先级,而代码更改很少。

      我在使用 lockFree-SkipList 之前写过一个,但这里有一个使用普通跳过列表的项目 (http://www.codeproject.com/KB/recipes/PriorityQueueSkipList.aspx)。我使用了一个跳过列表,因为它们在并发下表现良好并且实现起来非常简单(减去无锁版本)。

      我还在 CodePlex 上看到了一个使用红黑树的优先级队列,但我现在找不到它。 更新:我考虑的优先级队列实现是 NGenerics 项目的一部分:http://code.google.com/p/ngenerics/

      【讨论】:

      • 非常感谢您的建议!我没有选择这个作为答案,但我非常感谢您的意见!
      • 好好编码!!祝你的项目好运:-)
      猜你喜欢
      • 2013-09-20
      • 2021-07-23
      • 2019-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2021-07-28
      相关资源
      最近更新 更多