c# AutoResetEvent和ManualResetEvent

網上有不少AutoResetEvent和ManualResetEvent的詳細介紹,在這裏不作過多詳細的解釋,寫下本身的一點心得留做備忘。多線程

AutoResetEvent和ManualResetEvent都是事件鎖,事件的功能就是能夠在被監控者發生某種變化後當即通知監控者並作出相應反應。函數

在使用多線程過程當中,鎖幾乎是不可缺乏的一項,咱們拿信號量和事件鎖舉例來講。spa

若是有一個廚師和一羣顧客,若是是使用信號量的話,狀況以下:顧客詢問廚師:「飯作好了嗎?」,廚師:「尚未好,等一會吧!」,顧客繼續等待一段時間後繼續詢問,循環往復,直到飯作好後開始吃飯。線程

若是採用事件鎖的話,狀況以下:廚師告訴顧客:「你先等一會吧,飯作好後,我告訴你!」,顧客等待,廚師告訴顧客:「飯作好了,你過來吃吧!」,顧客吃飯。在這種模式下,使用事件鎖就會好一些。code

AutoResetEvent myAutoRetEvent = new AutoResetEvent(false);blog

ManualResetEvent myManualRetEvent = new ManualResetEvent(false);事件

//通知正在等待的線程已發生事件(廚師)it

//構造函數函數變量若是爲:false,初始狀態非終止狀態。廚師的初始狀態就很忙碌,顧客若是要吃飯就要等待。class

//構造函數變量若是爲:true,初始狀態爲終止狀態。廚師的初始狀態爲已經作好了飯,顧客能夠直接吃飯。監控

 

/// <summary>
        /// 通知正在等待的線程已發生事件 true:初始狀態爲終止狀態 false:初始狀態爲非終止狀態
        /// 目前的初始狀態未廚師沒有作飯
        /// </summary>
        private AutoResetEvent myAutoRetEvent = new AutoResetEvent(false);

        private void button2_Click(object sender, EventArgs e)
        {
            Thread myThread = new Thread(new ThreadStart(RunStart));
            myThread.Start();
            //廚師作飯作了3000ms
            Thread.Sleep(3000);
            //廚師告訴顧客飯作好了
            myAutoRetEvent.Set();
        }

        private void RunStart()
        {
            //顧客來了,要吃飯
            myAutoRetEvent.WaitOne();
            MessageBox.Show("吃飯...");
        }


單擊按鈕後,等待3秒後,彈出「吃飯...」,若是把構造函數中的false改成true,單擊按鈕後,當即彈出「吃飯...」。

而ManualResetEvent與AutoResetEvent的區別是:前者(廚師作好飯後,全部的顧客都開始吃飯),然後者(廚師作好飯後,只有一個顧客能吃到飯。)

 

AutoResetEvent:

/// <summary>
        /// 通知正在等待的線程已發生事件 true:初始狀態爲終止狀態 false:初始狀態爲非終止狀態
        /// 目前的初始狀態未廚師沒有作飯
        /// </summary>
        private AutoResetEvent myAutoRetEvent = new AutoResetEvent(false);

        private void button3_Click(object sender, EventArgs e)
        {
            //來了一個顧客1
            Thread myThread1 = new Thread(new ThreadStart(Run_1));
            myThread1.Start();
            //來了一個顧客2
            Thread myThread2 = new Thread(new ThreadStart(Run_2));
            myThread2.Start();

            //廚師作飯作3000ms
            Thread.Sleep(3000);
            //廚師作好飯了,通知看誰能吃上飯
            myAutoRetEvent.Set();
        }

        private void Run_1()
        {
            //顧客1過來了,要吃飯,等廚師作好飯
            myAutoRetEvent.WaitOne();
            MessageBox.Show("我是顧客1開始吃飯...");
        }

        private void Run_2()
        {
            //顧客2過來了,要吃飯,等廚師作好飯
            myAutoRetEvent.WaitOne();
            MessageBox.Show("我是顧客2開始吃飯...");
        }

ManualResetEvent:

private ManualResetEvent myManualRetEvent = new ManualResetEvent(false);

        private void button4_Click(object sender, EventArgs e)
        {
            //來了一個顧客1
            Thread myThread3 = new Thread(new ThreadStart(Run_3));
            myThread3.Start();
            //來了一個顧客2
            Thread myThread4 = new Thread(new ThreadStart(Run_4));
            myThread4.Start();

            //廚師作飯作3000ms
            Thread.Sleep(3000);
            //廚師作好飯了,通知看誰能吃上飯
            myManualRetEvent.Set();
        }

        private void Run_3()
        {
            //顧客1過來了,要吃飯,等廚師作好飯
            myManualRetEvent.WaitOne();
            MessageBox.Show("我是顧客1開始吃飯...");
        }

        private void Run_4()
        {
            //顧客2過來了,要吃飯,等廚師作好飯
            myManualRetEvent.WaitOne();
            MessageBox.Show("我是顧客2開始吃飯...");
        }

廚師作好飯後,通知你們,全部等待的顧客都開始吃飯。二者的區別如上所述。

此篇文章是受csdn 陸敏技的文章啓發,便於本身的理解記憶。

相關文章
相關標籤/搜索