ManualResetEvent和AutoResetEvent在C#中用法比較類似,都是用來做線程式控制制的,這個從他們的名字
也可以看出。
先說相似點,他們都有對象方法:Set、Reset、WaitOne,用法類似,其中:
Set表示設定為有訊號狀態,這時調用WaitOne的線程將繼續執行;
Reset表示設定為無訊號狀態,這時調用WaitOne的線程將阻塞;
WaitOne表示在無訊號狀態時阻塞當前線程,也就是說WaitOne只有在無訊號狀態下才會阻塞線程。
再說說不同點,
“Manual”表示手動的,“Auto”表示自動的,那麼這個手動和自動的具體含義是什麼呢?請看下面的例子:
public class ResetEventTest { public void Test() { Thread t1 = new Thread(new ThreadStart(thread1)); Thread t2 = new Thread(new ThreadStart(thread2)); t1.Start(); t2.Start(); Thread.Sleep(1000); //讓執行過程停止1秒 _manualResetEvent.Set(); //設定為有訊號,如果把該行代碼注釋掉thread1 completed!和thread2 completed!是不會執行的,為什嗎? Console.ReadLine(); } private ManualResetEvent _manualResetEvent = new ManualResetEvent(false);//此處是設定初始狀態false表示無訊號狀態,true表示有訊號狀態 private void thread1() { Console.WriteLine("thread1 started!"); _manualResetEvent.WaitOne(); //_manualResetEvent.Reset(); Console.WriteLine("thread1 completed!"); } private void thread2() { Console.WriteLine("thread2 started!"); _manualResetEvent.WaitOne(); //_manualResetEvent.Reset(); //設定為無訊號 Console.WriteLine("thread2 completed!"); } }
上面代碼的執行結果為:
thread1 started!
thread2 started!
thread1 completed!
thread2 completed!
如果把上例中的ManualResetEvent改為AutoResetEvent可以看到thread1 completed!和thread2 completed!
其中一個是不會執行的,這是為什麼呢?
因為AutoResetEvent調用Set後會在第一個調用WaitOne後自動將訊號置為無訊號狀態導致其他調用WaitOne
的線程繼續阻塞,而ManualResetEvent不會自動化佈建訊號的狀態;在上例中把_manualResetEvent.Reset()前
面的注釋去掉,再運行會得到同樣的效果。