【问题标题】:Suspending and notifying threads when there is work to do当有工作要做时暂停和通知线程
【发布时间】:2008-10-16 19:54:15
【问题描述】:

我有多个线程(在 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。

【问题讨论】:

    标签: c# multithreading


    【解决方案1】:

    查看WaitHandle 及其降级。 EventWaitHandle 可能适合您的需求。

    【讨论】:

    • 我正要说同样的话。在我不久前写的一些代码中,我们使用 AutoResetEvent 进行类似的线程同步
    【解决方案2】:

    与 Kent 指出的 WaitHandle 类一样,简单的Monitor.Wait 和 Monitor.Pulse/PulseAll 可以轻松做到这一点。它们比事件句柄“更轻”,尽管更原始一些。 (您不能在多台显示器上等待等)

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

    【讨论】:

      【解决方案3】:

      在您的场景中,也可以直接使用ThreadPool 类。这意味着您无需设置将要使用的线程,它还允许您根据要完成的工作设置线程。

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-05-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多