2010-08-23 43 views
3

作为Windows服务 我接受在一个单独的线程使用 myListener.BeginAcceptSocket(acceptAsync, null)如何阻塞,直到线程返回到池中?

传入套接字连接acceptAsync函数执行的一部分(正如预期)。

当服务被请求关闭时,我“发信号”接受并正在插座上工作的线程完成。

在发信号通知每个线程结束后,我需要阻止,直到它们全部完成。我有一个线程列表,我想我可以遍历每个线程,直到完成所有线程。

看起来这些线程似乎并没有结束,但返回到池中,所以Join会永远等待。

如何阻塞,直到一个线程返回池?

回答

3

这样做的规范模式是使用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(); 
    } 
    } 
} 
4

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

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

1

最好的办法是改变acceptAsync,以便它在信号量上发出信号,然后主线程可以等待该信号量。

您对Threapool线程没有太多权限或控制权。

+0

我其实比我更喜欢这个,因为您只需要为所有线程提供一次性资源,而不是我的,每个线程需要一次性资源。 – casperOne 2010-08-23 20:23:52