在C#中异步处理项目队列

时间:2012-01-25 03:40:10

标签: c# multithreading queue

我正在尝试创建一个处理工作队列的系统。该系统具有以下规格:

  1. 系统有两个组件,工作分配器和工人。
  2. 同时运行的工人数量设定了上限。该上限大于一。
  3. 为避免同一任务被处理两次出现问题,只有一个工作分配者。
  4. 您将使用什么样的设计来创建这样的系统?这就是我的想法:

    1. 创建一个队列集合,每个工作人员一个队列
    2. 为工作分配者创建一个计时器。它的工作是填充队列。
    3. 为每个工作人员创建一个计时器,将队列对象作为对象状态传递以表示其工作负载
    4. 在锁定队列时删除并添加到队列中。
    5. 使用在锁定时递增和递减的计数器,以确保同时运行的指定工作任务数不超过指定数量。
    6. 我觉得必须有更好的方法来做到这一点。你会推荐什么?我应该从工作人员的计时器切换到线程吗?在队列为空时,线程是否应该旋转/等待?如果线程关闭并让工作分配器有条件地创建一个新的?

3 个答案:

答案 0 :(得分:10)

我不知道您的任务将运行多长时间,但似乎最好的办法是使用ThreadPool。 此外,我会使用,实际上只使用了一个中央队列 - 仅此一项将消除一些复杂性。 我有一个处理队列的线程,并在你的情况下对项目执行操作,它将对任务进行排队。

至于使队列线程安全,System.Collections.Concurrent中有一个ConcurrentQueue用于此目的(msdnbenchmark vs locking queue)。

现在,抛出一个BlockingCollection(msdn),你就拥有了所需的一切。

        BlockingCollection<Packet> sendQueue = new BlockingCollection<Packet>(new ConcurrentQueue<Packet>());
        while (true)
        {
            var packet = sendQueue.Take(); //this blocks if there are no items in the queue.
            ThreadPool.QueueUserWorkItem(state =>
            {
               var data = (Packet)state;
               //do whatever you have to do
            }, packet );
        }

某处有sendQueue.Add(packet);

总结一下,

  1. 所有“工人”的一个队列
  2. 从队列中出队的一个线程 并将其传递给ThreadPool。
  3. 我认为就是这样。

    ps:如果你必须控制线程数量,请使用josh3736建议的“智能线程池”

答案 1 :(得分:3)

使用线程池。 Here's one that handles the queueing of work items并将它们分配到线程池中。

答案 2 :(得分:0)

你走在正确的道路上。您可以使用MSMQ和多线程C#服务。我开始用这个article编写C#多线程服务了。这篇文章已经有了一些年龄,但原则并没有改变,所以它是相关的。它很容易理解,更好,但它探索了你建议的两种方法。如果您需要其他帮助,请随时给我发电子邮件。