【问题标题】:How do I block until a thread is returned to the pool?在线程返回池之前如何阻塞?
【发布时间】:2010-08-23 19:53:34
【问题描述】:

作为 Windows 服务的一部分 我正在接受传入的套接字连接 myListener.BeginAcceptSocket(acceptAsync, null)

acceptAsync 函数在单独的线程上执行(正如预期的那样)。

当服务被请求关闭时,我“通知”接受并当前正在处理套接字的线程结束。

在通知每个线程结束后,我需要阻塞直到它们都完成。我有一个线程列表,我认为我可以遍历每个线程并 Join 直到它们全部完成。

但是,这些线程似乎并没有结束,而是返回到池中,所以 Join 将永远等待。

在线程返回池之前如何阻塞?

【问题讨论】:

    标签: c# .net multithreading


    【解决方案1】:

    在这种情况下,您不应该使用 Join。相反,您应该使用一系列 WaitHandles(特别是 AutoResetEvent 或 ManualResetEvent),您的线程在完成工作时会发出信号。

    然后您将调用static WaitAll method on the WaitHandle 类,传递所有要等待的事件。

    【讨论】:

      【解决方案2】:

      执行此操作的规范模式是使用CountdownEvent。主线程将增加事件以表明它正在参与,并且工作线程一旦启动就会执行相同的操作。工作线程完成后,他们将减少事件。当主线程准备好等待完成时,它应该减少事件然后等待它。如果您没有使用 .NET 4.0,那么您可以从 Joe Albahari's threading ebook 的第 4 部分获得倒计时事件的实现。

      public class Example
      {
        private CountdownEvent m_Finisher = new CountdownEvent(0);
      
        public void MainThread()
        {
          m_Finisher.AddCount();
      
          // Your stuff goes here.
          // myListener.BeginAcceptSocket(OnAcceptSocket, null);
      
          m_Finisher.Signal();
          m_Finisher.Wait();
        }
      
        private void OnAcceptSocket(object state)
        {
          m_Finisher.AddCount()
          try
          {
            // Your stuff goes here.
          }
          finally
          {
            m_Finisher.Signal();
          }
        }
      }
      

      【讨论】:

        【解决方案3】:

        最好的方法是更改​​acceptAsync 使其在信号量上发出信号,然后您的主线程可以在该信号量上等待。

        您没有太多访问或控制 Thrapool 线程的权限。

        【讨论】:

        • 我实际上比我更喜欢这个,因为您只需要为所有线程提供一个一次性资源,而我的每个线程需要一个一次性资源。
        猜你喜欢
        • 2016-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-22
        • 1970-01-01
        • 2015-07-19
        • 1970-01-01
        相关资源
        最近更新 更多