Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中异步处理项目队列#_C#_Multithreading_Queue - Fatal编程技术网

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

C# 在C中异步处理项目队列#,c#,multithreading,queue,C#,Multithreading,Queue,我正在尝试创建一个处理工作队列的系统。该系统具有以下规格: 该系统有两个组件,一个工作分配者和一个工人 同时运行的工人数量有一个设定的上限。这个上限大于一 为了避免同一任务被处理两次的问题,只有一个工作分配者 您将使用什么设计来创建这样一个系统?以下是我的想法: 创建队列集合,每个工作人员一个队列 为工作分配者创建计时器。它的任务是填充队列 为每个worker创建一个计时器,传入一个队列对象作为对象状态以表示其工作负载 在队列被锁定时将其删除并添加到队列中 使用在锁定时递增和递减的计数器,以确保

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

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

  • 创建队列集合,每个工作人员一个队列
  • 为工作分配者创建计时器。它的任务是填充队列
  • 为每个worker创建一个计时器,传入一个队列对象作为对象状态以表示其工作负载
  • 在队列被锁定时将其删除并添加到队列中
  • 使用在锁定时递增和递减的计数器,以确保同时运行的辅助任务不超过指定数量

  • 我觉得一定有更好的办法。你推荐什么?我应该为工人从计时器切换到线程吗?当队列为空时,线程是否应该旋转/等待?线程是否应该关闭,并让工作分配程序有条件地创建一个新线程

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

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

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

    现在,加入BlockingCollection(),您就拥有了所需的一切

            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 );
            }
    
    BlockingCollection sendQueue=new BlockingCollection(new ConcurrentQueue());
    while(true)
    {
    var packet=sendQueue.Take();//如果队列中没有项目,则此操作将阻塞。
    ThreadPool.QueueUserWorkItem(状态=>
    {
    var数据=(数据包)状态;
    //做你必须做的事
    },数据包);
    }
    
    在某个地方有一些东西
    sendQueue.Add(packet)

    总之,

  • 所有“工人”的一个队列
  • 从队列中退出队列的一个线程 并将其传递到线程池
  • 我想就是这样

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