C#執行緒同步自動重置事件——AutoResetEvent

桃子夭夭發表於2015-08-20

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

相關文章