下面是一個說明我的問題的方法'SomeMethod'的類。如何解鎖已在AutoResetEvent對象上調用WaitOne方法的線程?
class SomeClass
{
AutoResetEvent theEvent = new AutoResetEvent(false);
// more member declarations
public void SomeMethod()
{
// some code
theEvent.WaitOne();
// more code
}
}
該方法的設計是線程安全的,將在不同的線程中調用。現在我的問題是如何在任何時間點解鎖所有在'theEvent'對象上調用'WaitOne'方法的線程?這種要求經常出現在我的設計中,因爲我需要能夠正常停止並啓動我的多線程程序。在我看來,啓動一個多線程程序相當簡單,但要停止一個程序很困難。
這是我迄今爲止試過的顯然有效的東西。但這是標準方法嗎?
public void UnblockAll()
{
do
{
theEvent.Set();
} while (theEvent.WaitOne(0));
}
'UnblockAll'方法是'SomeClass'類的成員。此處使用的技術基於WaitOne method的MSDN文檔。我引用以下文檔的相關部分:
如果毫秒超時爲零,則該方法不會阻塞。它測試等待句柄的狀態並立即返回。
在do..while循環中,我調用Set method。這釋放了由於對WaitOne方法的調用而被阻塞的單個線程(在'SomeMethod'方法中編碼)。接下來,我測試'theEvent'對象的狀態,以瞭解它是否有信號。這個測試是通過調用WaitOne方法的超載版本來完成的,該方法需要超時參數。我在調用WaitOne方法時使用的參數爲零,根據文檔結果,調用立即返回一個布爾值。如果返回值爲true,那麼處於信號狀態的'theEvent'對象爲。如果在'SomeMethod'方法中調用'WaitOne'方法時至少有一個線程被阻塞,那麼對'Set'方法的調用(在'UnblockAll'方法中編碼)將會解除阻塞。因此,在'UnblockAll'方法中do..while語句結束時對'WaitOne'方法的調用將返回false。只有在沒有線程被阻塞的情況下,返回值才爲真。
上述推理是否正確,如果是對的,該技術是解決我的問題的標準方法嗎?我正在嘗試主要在.net compact-framework 2.0平臺上使用該解決方案。
題外話 - 你不能調用變量 - 「事件」 – Maxim 2011-05-09 17:14:42
聽起來像你想的ManualResetEvent來代替。這樣,即使您有多個偵聽器,它也會保持設置。 – 2011-05-09 20:41:12
@Maxim。糾正了代碼中的語法錯誤.. – ghd 2011-05-10 04:16:30