AutoResetEvent物件用來進行執行緒同步操作,AutoResetEvent類繼承waitHandle類。
AutoResetEvent物件有終止和非終止兩種狀態,終止狀態是執行緒繼續執行,非終止狀態使執行緒阻塞,可以呼叫set和reset方法使物件進入終止和非終止狀態。AutoResetEvent顧名思義,其物件在呼叫一次set之後會自動呼叫一次reset,進入非終止狀態使呼叫了等待方法的執行緒進入阻塞狀態。
waitHandle物件的waitone可以使當前執行緒進入阻塞狀態,等待一個訊號。直到當前 waitHandle物件收到訊號,才會繼續執行。
set可以傳送一個訊號,允許一個或多個因為呼叫waitone而等待執行緒繼續執行,經實驗,如果有多個等待的執行緒,一次set只能讓一個執行緒繼續執行。
reset可以使因為呼叫waitone而等待執行緒都進入阻塞狀態。
下面的例子是啟動了兩個執行緒,用AutoResetEvent物件來讓他們阻塞或者繼續。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace myTest { class Program { const int numIterations = 5; //initialState 若要一開始就是阻塞的,則設為false,一開始是非阻塞的,則設為true。 static AutoResetEvent myResetEvent = new AutoResetEvent(false); static int number=0; static void Main(string[] args) { Thread myReaderThread = new Thread(new ThreadStart(MyReadThreadProc)); myReaderThread.Name = "ReaderThread"; myReaderThread.Start(); Thread myReaderThread2 = new Thread(new ThreadStart(MyReadThreadProc2)); myReaderThread2.Name = "ReaderThread2"; myReaderThread2.Start(); //myResetEvent.Reset(); // 設為終止狀態,讓 waitone的執行緒阻塞 for (int i = 1; i <= numIterations; i++) { Console.WriteLine("Writer thread writing value: {0}", i); number = i; //將事件狀態設定為終止狀態,允許一個或多個等待執行緒繼續。 myResetEvent.Set(); Thread.Sleep(2000); myResetEvent.Set(); //休息一下,讓執行緒1和2來得及執行 Thread.Sleep(2000); } myReaderThread.Abort(); Console.ReadLine(); } static void MyReadThreadProc() { while (true) { // 阻止當前執行緒,直到 Threading.waitHandler 收到一次訊號 myResetEvent.WaitOne(); Console.WriteLine("Thread1: {0} reading value: {1}", Thread.CurrentThread.Name, number); } } static void MyReadThreadProc2() { while (true) { // 阻止當前執行緒,直到 Threading.waitHandler 收到一次訊號 myResetEvent.WaitOne();
Console.WriteLine(DateTime.Now.ToString()); Console.WriteLine("Thread2:{0} reading value: {1}", Thread.CurrentThread.Name, number); } } } }
執行結果:
在結果中可以看到,如果有多個執行緒等待,每次set之後只有一個執行緒繼續執行,且繼續執行的執行緒是隨機的。