gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-30 00:08:23 28 4
gpt4 key购买 nike

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

  1. 该系统有两个组件,一个工作分配器和一个工作人员。
  2. 同时运行的 worker 数量是有上限的。该上限大于一。
  3. 为避免同一任务被处理两次的问题,只有一个工作分配者。

您会使用什么设计来创建这样的系统?这是我的想法:

  1. 创建队列集合,每个工作人员一个队列
  2. 为工作分配者创建一个计时器。它的工作是填充队列。
  3. 为每个worker创建一个Timer,传入一个队列对象作为对象状态来表示其工作量
  4. 在队列锁定时删除和添加队列。
  5. 使用在锁定时递增和递减的计数器,以确保同时运行的工作任务不超过指定数量。

我觉得一定有更好的方法来做到这一点。你会推荐什么?我应该为 worker 从定时器切换到线程吗?线程是否应该在队列为空时旋转/等待?线程是否应该关闭并让工作分配者有条件地创建一个新线程?

最佳答案

我不知道您的任务将运行多长时间,但似乎最好的办法是使用 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. 所有“ worker ”的队列
  2. 一个从队列中出队的线程并将其传递给线程池。

我想就是这样。

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

关于c# - 在 C# 中异步处理项目队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8997542/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com