AutoResetEvent和ManualResetEvent用於多線程之間代碼執行順序的控制,它們繼承自WaitHandle,API相同,但在使用中還是有區別的。
每次使用時雖然理解了,但由於沒有去深入思考記憶,過幾天又忘記了。到下次需要使用的時候又要重新去理解這2個類。
今天再次遇到他們,寫下這篇隨筆。。加深理解印象。以後不用去糾結他們了。
var manualResetEventWaitHandle = new ManualResetEvent(true);
var autoResetEventResetEventWaitHandle = new AutoResetEvent(true);
MSDN的解釋:True有信號,False無信號
為True,代碼執行過程中遇到WaitHandle.WaitOne()的時候,(有了信號)不會阻塞該線程,將會繼續執行下去。
如為False,遇到WaitHandle.WaitOne()的時,當前線程被掛起(沒有信號,等待信號),直到另一個線程執行WaitHandle.Set(),線程才會繼續執行WaitHandle.WaitOne後面的代碼
MSDN的解釋:Set為終止狀態(有信號),Reset設置為非終止狀態(沒有信號)
結合構造函數的參數這樣比較好理解了。
var waitHandle = new ManualResetEvent/AutoResetEvent(false)
waitHandle.Set()
等價於
var waitHandle = new ManualResetEvent/AutoResetEvent(true)
同理
var waitHandle = new ManualResetEvent/AutoResetEvent(true)
waitHandle.Reset()
等價於
var waitHandle = new ManualResetEvent/AutoResetEvent(false)
輪到主角了。以地鐵閘機為比喻,閘機開啟(沒有信號) 乘客來到閘機前無法通行(WaitOne),刷卡(Set)後,閘機關閉(有信號),乘客進入。然後閘機再開啟(沒信號),
高亮就是它們的區別了。可以想象一般情況下閘機是一個AutoResetEvent,每當通過一個客人後,閘機又開啟,閘機遇到了故障第一個人刷卡進入後,閘機還是處於關閉,這樣之後的乘客不用WaitOne可以繼續進入
也就是
autoResetEventResetEventWaitHandle.Set()
等同於
manualResetEventWaitHandle.Set()
manualResetEventWaitHandle.Reset();
Framework4中的ManualResetEvent輕量級優化版,推薦使用
http://www.cnblogs.com/qingyun163/archive/2013/01/05/2846633.html
http://baike.baidu.com/link?url=Cu-Oakr8hkaYtpg9hPTMuuUtAiMdSBc-f_LCs3-dtWTcYSIvbl9b22AKi63MyZ3I9RtmYtUCnYtVFsjTrQiNVq