初次體驗
ManualResetEvent和AutoResetEvent主要負責多線程編程中的線程同步;以下一段是引述網上和MSDN的解析:
在.Net多線程編程中,AutoResetEvent和ManualResetEvent這兩個類經常用到, 他們的用法很類似,但也有區別。Set方法將信號置爲發送狀態,Reset方法將信號置爲不發送狀態,WaitOne等待信號的發送。可以通過構造函數的參數值來決定其初始狀態,若爲true則非阻塞狀態,爲false爲阻塞狀態。如果某個線程調用WaitOne方法,則當信號處於發送狀態時,該線程會得到信號, 繼續向下執行。其區別就在調用後,AutoResetEvent.WaitOne()每次只允許一個線程進入,當某個線程得到信號後,AutoResetEvent會自動又將信號置爲不發送狀態,則其他調用WaitOne的線程只有繼續等待.也就是說,AutoResetEvent一次只喚醒一個線程;而ManualResetEvent則可以喚醒多個線程,因爲當某個線程調用了ManualResetEvent.Set()方法後,其他調用WaitOne的線程獲得信號得以繼續執行,而ManualResetEvent不會自動將信號置爲不發送。也就是說,除非手工調用了ManualResetEvent.Reset()方法,則ManualResetEvent將一直保持有信號狀態,ManualResetEvent也就可以同時喚醒多個線程繼續執行。
本質上AutoResetEvent.Set()方法相當於ManualResetEvent.Set()+ManualResetEvent.Reset();
因此AutoResetEvent一次只能喚醒一個線程,其他線程還是堵塞
生動示例
用一個三國演義的典故來寫段示例代碼:
話說曹操率領80W大軍準備圍剿劉備和孫權,面對敵衆我寡的情況,諸葛亮與周瑜想到了一個妙計,用裝滿火藥桶的大船去衝擊曹操連在一起的戰船,計劃都安排好了,可謂“萬事俱備 只欠東風”。
02 |
using
System.Collections.Generic; |
05 |
using
System.Threading; |
12 |
private
static
ManualResetEvent mre = new
ManualResetEvent( false );
|
14 |
static
void
Main( string [] args)
|
16 |
EastWind wind =
new
EastWind(mre); |
18 |
Thread thd =
new
Thread( new
ThreadStart(wind.WindComming)); |
24 |
Console.WriteLine( "諸葛亮大吼:東風來了,可以進攻了,滿載燃料的大船接着東風衝向曹操的戰船" );
|
34 |
ManualResetEvent _mre;
|
39 |
/// <param name="mre"></param>
|
40 |
public
EastWind(ManualResetEvent mre) |
48 |
public
void
WindComming() |
50 |
Console.WriteLine( "東風正在吹過來" );
|
51 |
for
( int
i = 0; i <= 5; i++) |
54 |
Console.WriteLine( "東風吹啊吹,越來越近了..." );
|
56 |
Console.WriteLine( "東風終於到了" );
|
運行結果: