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之后只有一個線程繼續執行,且繼續執行的線程是隨機的。