2010-11-04 18 views
2

我注意到,根據指示,我的一些服務掛起而不是關閉,因爲他們正在等待其他服務持有的鎖等待它們關閉(造成死鎖)。爲此,我需要一些方法來發出信號等待鎖關閉線程,所以我想出了這個:我怎麼能指示線程停止等待一個Mutex加入後呢?

public static Boolean Lock(this Mutex mutex) 
{ 
Boolean achieved = false; 

while (Thread.CurrentThread.ThreadState != System.Threading.ThreadState.StopRequested) 
{ 
    try 
    { 
    achieved = mutex.WaitOne(TimeSpan.FromSeconds(10.0)); 
    } 
    catch (AbandonedMutexException exception) 
    { 
    // Log this 
    } 
} 

return achieved; 
} 

當每個服務被停止,它要求加入它的每個線程。問題是即使在調用Thread之後,ThreadState仍然被設置爲Running。最終,Join會超時並且線程會中止,但我寧願它不會這樣做。

所以我有兩個問題:

  1. 有一些方法的線程知道它已經加入了(因此停止等待)?

  2. 有沒有更好的方法來解決這個問題比我在這裏提出的?

回答

2

創建一個全球性的手動重置事件,加入你的線程之前在服務關閉設置,並在您Lock功能使用WaitHandle.WaitAny (mutex, stopEvent)

internal static EventWaitHandle s_stopEvent ; 

// in service startup code: 
s_stopEvent = new ManualResetEvent (false) ; 

public static void Stop (this IEnumerable<Thread> threads) 
{ 
    s_stopEvent.Set() ; 
    foreach (var thread in threads) 
    thread.Join() ; 
} 

public static bool Lock (this Mutex mutex) 
{ 
    try 
    { 
    return WaitHandle.WaitAny (new WaitHandle[] { mutex, s_stopEvent }) == 0 ; 
    } 
    catch (AbandonedMutexException exception) 
    { 
    // Log this 
    } 
} 
+0

你能詳細解釋一下嗎? – 2010-11-04 19:15:48

1

您必須在線程正在運行的任務中構建取消機制,因此除了取消之外,沒有線程機制可以提供幫助。

看一看這裏:

http://www.albahari.com/threading/part3.aspx#_Cancellation_Tokens

+0

是取消令牌取代我的連接的想法,並且當我希望我的線程關閉時,拋出並捕獲取消異常?這看起來有點像墮胎,因爲它無視國家。這是不錯的做法嗎?有沒有辦法更優雅地做到這一點? – 2010-11-04 19:19:33

+0

是的,這是取代您的加入的另一種方法。工作線程正在執行的操作將包括檢查已取消的標誌,在這種情況下他們將停止並且不需要連接。 – Aliostad 2010-11-04 23:11:45

相關問題