Multithreading “我应该把它放在哪里?”;当作业1。。n完成了吗?“;

Multithreading “我应该把它放在哪里?”;当作业1。。n完成了吗?“;,multithreading,language-agnostic,Multithreading,Language Agnostic,我有一些并行代码和线程池 我分派要完成的作业组,我需要分派15个作业,比如说,当所有15个作业都完成时,应该执行这个特殊作业“作业16” 您不能将“作业16”排在最后一个队列中,让线程池“准备就绪时执行”,因为它可能会在作业13、14、15完成之前启动“作业16”的执行 所以,你需要有一种计数的方法。我的问题是,责任在哪里 调用代码中的:使用在每个作业结束时递增的静态/全局变量。作业1-15执行计数器+。当计数器=15时,执行作业16 在线程池中:将功能添加到线程池中,以在“之前提交的作业(时

我有一些并行代码和线程池

我分派要完成的作业组,我需要分派15个作业,比如说,当所有15个作业都完成时,应该执行这个特殊作业“作业16”

您不能将“作业16”排在最后一个队列中,让线程池“准备就绪时执行”,因为它可能会在作业13、14、15完成之前启动“作业16”的执行

所以,你需要有一种计数的方法。我的问题是,责任在哪里

  • 调用代码中的:使用在每个作业结束时递增的静态/全局变量。作业1-15执行
    计数器+
    。当计数器=15时,执行作业16
  • 在线程池中:将功能添加到线程池中,以在“之前提交的作业(时间戳)未保留时”执行
  • 在回调中:(负责检查作业1-15是否完成,否则旋转/睡眠)

    • 我更喜欢第一种方法


      除了计数方法,您可以使用MalualReSeEvest[]数组来同步第十六个作业和剩余的15个作业。

      < P>您也可以考虑在自己的类中封装此行为,并在完成作业时引发一个事件,以触发对第十六个任务的排队,例如:

      internal class ParallelBatchRunner
      {
          public event EventHandler Completed = delegate { };
      
          public void Run(List<Action> tasks)
          {
              int count = tasks.Count;
      
              tasks.ForEach(t =>
              {
                  Action completionTask = () =>
                  {
                      t();
      
                      if (Interlocked.Decrement(ref count) == 0)
                      {
                          Completed(this, EventArgs.Empty);
                      }
                  };
      
                  ThreadPool.QueueUserWorkItem(_ => completionTask());
              });
          }
      }
      
      内部类ParallelBatchRunner
      {
      public event EventHandler Completed=委托{};
      公共作废运行(列出任务)
      {
      int count=tasks.count;
      tasks.ForEach(t=>
      {
      操作完成任务=()=>
      {
      t();
      if(联锁减量(参考计数)==0)
      {
      已完成(此,EventArgs.Empty);
      }
      };
      ThreadPool.QueueUserWorkItem(=>completionTask());
      });
      }
      }
      
      请注意,
      计数器+++
      不是线程安全的。你可以打个电话,我最后做了类似的事情。每个
      ParallelBatchRunner
      都有一个计数器,当计数器达到批大小并且批中的最后一个作业完成时,将调用一个函数
      BatchReady()
      ,该函数将启动下一批。