2010-08-23 41 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