[C#.NET][Thread] 執行緒同步機制 - AutoResetEvent / ManualResetEvent
這兩個類別AutoResetEvent 類別、ManualResetEvent 類別的WaitOne方法可以使執行緒進入Blocks變成WaitSleepJoin狀態,Set方法可以進入Waitting回到Running狀態。
所以我們可以用它們來等候其他的執行緒進而達到資料同步機制,而他們兩個的用法很像,
1.當使用Set方法後AutoResetEvent會自動處於未收到信號的狀態,而ManualResetEvent必須要再呼叫Reset方法後才會處於未收到信號的狀態。
2.AutoResetEvent 與 ManualResetEvent 是衍生自新的 EventWaitHandle 類別,AutoResetEvent 的功能相等於以 EventResetMode.AutoReset 。ManualResetEvent 的功能等於以 EventResetMode.ManualReset。
3.AutoResetEvent 一次只能喚醒一個執行緒,ManualResetEvent可以喚醒多個執行緒
4.ManualResetEvent,使用WaitOne鎖定後,必須要再呼叫Reset方法,使其回到未鎖定狀態;AutoResetEvent 就不必呼叫Reset方法,會自動的回到未鎖定狀態。
接下來我們用程式碼來演練觀察其狀態
按F5來看看,我們可以看到當執行緒進入到ThreadMethod方法並執行第37行的_AutoWait方法後,並沒有往下執行到40行,反而是直接印出第28行的資料,直到執行30行的_AutoWait.Set方法後才有印出40行的訊息,WaitOne的方法確實的鎖定了執行緒,狀態也是WaitSleepJoin。
再來一樣利用上段程式碼來觀察,這次來看ManualResetEvent,解開_ManualWait的註解
果然,被鎖定的執行緒一次全部被喚醒了
所以我們可以把EventWaitHandle.WaitOne方法用來當成暫停,EventWaitHandle.Set方法當成繼續,就不要用Thread.Suspend / Thread.Resume這兩個危險的方法了。
也可以看看MSDN上的例子使用WaitHandle.WaitAll方法來等待所有執行緒完成,用以達到同步機制。
http://msdn.microsoft.com/zh-tw/library/system.threading.manualresetevent.aspx
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET