C#理解AutoResetEvent和ManualResetEvent

    當在C#使用多線程時就免不了使用AutoResetEvent和ManualResetEvent類,能夠理解這兩個類能夠經過設置信號來讓線程停下來或讓線程從新啓動,其實與操做系統裏的信號量很類似(汗,考完考試已經有點忘記了)。下面上代碼編程

    class Program
    {
        const int count = 10;
        //賦值爲false也就是沒有信號
        static AutoResetEvent myResetEvent = new AutoResetEvent(false);
        static int number;
        static void Main(string[] args)
        {
            Thread thread = new Thread(funThread);
            thread.Name = "QQ";
            thread.Start();
            for (int i = 1; i < count; i++)
            {
                Console.WriteLine("first number: {0}",i);
                number = i;
                //這裏是設置爲有信號
                myResetEvent.Set();
                Thread.Sleep(2000);
            }
            thread.Abort();
        }

        static void funThread()
        {
            while (true)
            {
                //執行到這個地方時,會等待set調用後改變了信號才接着執行
                myResetEvent.WaitOne();
                Console.WriteLine("end {0} number: {1}", Thread.CurrentThread.Name, number);
            }
        }

    }

輸出結果爲多線程

first number:1函數

end QQ number:1spa

first number:2操作系統

end QQ number:3線程

.....code

   簡單來講只有調用Set()方法後才能執行WaitOne()後面的代碼,AutoResetEvent和ManualResetEvent分別都有Set()改變爲有信號 ,Reset()改變爲無信號,WaitOne()將會阻塞當前調用的線程,直到有信號爲止,即執行了Set()方法,WaitOne()方法還能夠帶指定時間的參數。對象

   理解了AutoResetEvent後再理解ManualResetEvent也就不難了,AutoResetEvent與ManualResetEvent的區別是,AutoResetEvent.WaitOne()會自動改變事件對象的狀態,即AutoResetEvent.WaitOne()每執行一次,事件的狀態就改變一次,也就是從無信號變爲有信號,或從有信號變爲無信號。而ManualResetEvent則是調用Set()方法後其信號量不會自動改變,除非再設置Reset()方法。blog

   在.Net多線程編程中,AutoResetEvent和ManualResetEvent這兩個類常常用到, 他們的用法很相似,但也有區別。Set方法將信號置爲發送狀態,Reset方法將信號置爲不發送狀態,WaitOne等待信號的發送。能夠經過構造函數的參數值來決定其初始狀態,若爲true則非阻塞狀態,爲false爲阻塞狀態。若是某個線程調用WaitOne方法,則當信號處於發送狀態時,該線程會獲得信號, 繼續向下執行。其區別就在調用後,AutoResetEvent.WaitOne()每次只容許一個線程進入,當某個線程獲得信號後,AutoResetEvent會自動又將信號置爲不發送狀態,則其餘調用WaitOne的線程只有繼續等待.也就是說,AutoResetEvent一次只喚醒一個線程;而ManualResetEvent則能夠喚醒多個線程,由於當某個線程調用了ManualResetEvent.Set()方法後,其餘調用WaitOne的線程得到信號得以繼續執行,而ManualResetEvent不會自動將信號置爲不發送。也就是說,除非手工調用了ManualResetEvent.Reset()方法,則ManualResetEvent將一直保持有信號狀態,ManualResetEvent也就能夠同時喚醒多個線程繼續執行。事件

相關文章
相關標籤/搜索