当有工作要做时,暂停并通知线程

时间:2008-10-16 19:54:16

标签: c# multithreading

我有多个线程(在IIS上运行的C#应用​​程序)运行,所有这些线程都需要与同一个MQ后端进行通信。为了最大限度地减少网络流量,我只需要在有工作要做的时候发送后端请求。将有一个线程来监视是否有工作要做,并且需要通知其他线程他们也应该开始处理。当前的解决方案涉及监视器线程设置一个全局变量并让其他线程循环并检查,即在监视器线程中:

CheckIfWorkAvailable() {
  while(true) {
    if (queue.Empty != true) {
      workToBeDone = true;
    }
  }//end while loop
}

然后在工作线程中:

DoWork() {
  while(true) {
    if (workToBeDone == true) {
      //do work...
    }
    else {
      Thread.Sleep(x seconds)
    }
  }//end while loop
}

监视器线程是否可以在有工作要做时通知工作线程而不是让它们循环和休眠?工作线程还设置一个计数器,指示它们正在工作,并在工作完成时减少它,因此workToBeDone标志可以设置为false。

5 个答案:

答案 0 :(得分:4)

查看WaitHandle及其降序类。 EventWaitHandle可能符合您的需求。

答案 1 :(得分:4)

与Kent指出的WaitHandle类一样,简单的Monitor.Wait和Monitor。Pulse / PulseAll可以轻松完成。它们比事件处理“更轻”,虽然有些更原始。 (您不能在多台显示器上等待等等。)

我在threading article中有一个这样的例子(作为生产者消费者队列)。

答案 2 :(得分:1)

在您的方案中,也可以直接使用ThreadPool类。这意味着您不需要设置将要使用的线程,并且还允许您根据要完成的工作来设置线程。

如果您在项目中使用CTP,可能需要查看TPL,因为它有一些更高级的同步和任务功能。

答案 3 :(得分:0)

使用ManualResetEvent来处理您希望所有工作线程在满足状态时继续运行的情况(看起来像您想要的那样)。如果您只希望在每次某些工作可用时向单个工作人员发出信号,请使用AutoResetEvent。如果要允许特定数量的线程继续,请使用信号量。几乎从不对这类事物使用全局变量,如果这样做,请将其标记为易失性。

在这种情况下要小心。您不希望导致“锁定车队”发生,因为每次释放单个项目时,您释放所有工作人员以立即全部命中队列,只需要再次等待。

答案 4 :(得分:-1)