C#AutoResetEvent和ManualResetEvent的區別

來源:互聯網
上載者:User

標籤:

一:終止狀態和非終止狀態    首先說說線程的終止狀態和非終止狀態。AutoResetEvent和ManualResetEvent的建構函式中,都有bool變數來指明線程的終止狀態和非終止狀態。true表示終止狀態(個人理解也就是可運行狀態,根據理解應該是該線程的阻塞終止了),false表示非終止狀態。
         AutoResetEvent _autoResetEvent = new AutoResetEvent(false);        private void BT_Temp_Click(object sender, RoutedEventArgs e)         {             Thread t1 = new Thread(this.Thread1Foo);             t1.Start();             Thread.Sleep(3000); //Thread.Sleep(Int32)是批當前進程掛起3000毫秒,與線程t1是一點關係也沒有的。            _autoResetEvent.Set();         }        void Thread1Foo()         {             _autoResetEvent.WaitOne();             MessageBox.Show("t1 end");         }     這段代碼的執行結果,就是3秒鐘過後,彈出“t1 end”。     而如果把:     AutoResetEvent _autoResetEvent = new AutoResetEvent(false);     改為:     AutoResetEvent _autoResetEvent = new AutoResetEvent(true);     則“t1 end”將會立刻彈出。     也就是說,在終止狀態中,_autoResetEvent.WaitOne()是不會起到阻滯背景工作執行緒的作用的。(PS:ManualResetEvent也同樣)二:AutoResetEvent和ManualResetEvent的區別 

       AutoResetEvent 允許線程通過發訊號互相通訊。 通常,當線程需要獨佔訪問資源時使用該類。

       線程通過調用 AutoResetEvent 上的 WaitOne 來等待訊號。 如果 AutoResetEvent 為非終止狀態,則線程會被阻止,並等待當前控制資源的線程通過調用 Set來通知資源可用。

       調用 Set 向 AutoResetEvent 發訊號以釋放等待線程。 AutoResetEvent 將保持終止狀態,直到一個正在等待的線程被釋放,然後自動返回非終止狀態。 如果沒有任何線程在等待,則狀態將無限期地保持      為終止狀態。如果當 AutoResetEvent 為終止狀態時線程調用 WaitOne,則線程不會被阻止。 AutoResetEvent 將立即釋放線程並返回到非終止狀態

 

     AutoResetEvent _autoResetEvent = new AutoResetEvent(false);         private void BT_Temp_Click(object sender, RoutedEventArgs e)         {             Thread t1 = new Thread(this.Thread1Foo);             t1.Start();             Thread t2 = new Thread(this.Thread2Foo);             t2.Start();             Thread.Sleep(3000);             _autoResetEvent.Set();         }        void Thread1Foo()         {             _autoResetEvent.WaitOne();             MessageBox.Show("t1 end");         }        void Thread2Foo()         {             _autoResetEvent.WaitOne();             MessageBox.Show("t2 end");         }     該段代碼啟動並執行效果是,過3秒後,要麼彈出“t1 end”,要麼彈出“t2 end”,不會兩個都彈出。也就是說,其中一個進行將會結束,而另一個進程永遠不會結束。程式碼片段3:         ManualResetEvent _menuRestEvent = new ManualResetEvent(false);        private void BT_Temp_Click(object sender, RoutedEventArgs e)         {             Thread t1 = new Thread(this.Thread1Foo);             t1.Start();             Thread t2 = new Thread(this.Thread2Foo);             t2.Start();             Thread.Sleep(3000);             _menuRestEvent.Set();         }        void Thread1Foo()         {             _menuRestEvent.WaitOne();             MessageBox.Show("t1 end");         }        void Thread2Foo()         {             _menuRestEvent.WaitOne();             MessageBox.Show("t2 end");         }     該段代碼啟動並執行效果是,過3秒後,“t1 end”和“t2 end”,兩個都被彈出。也就是說,兩個進程都結束了。     這個特性就是說,AutoResetEvent只會給一個線程發送訊號,而不會給多個線程發送訊號。在我們需要同步多個線程的時候,就只能採用ManualResetEvent了。至於深層次的原因是,AutoResetEvent在set()之後,會將線程     狀態自動置為false,而ManualResetEvent在Set()後,線程的狀態就變為true了,必須手動ReSet()之後,才會重新將線程置為false。這也就是為什麼他們的名字一個為Auto,一個為Manual的原因。為了更加充分的驗證Manua  lResetEvent的這點特性,我們再來看程式碼片段4程式碼片段4:     ManualResetEvent _menuRestEvent = new ManualResetEvent(false);        private void BT_Temp_Click(object sender, RoutedEventArgs e)         {             Thread t1 = new Thread(this.Thread1Foo);             t1.Start();             Thread t2 = new Thread(this.Thread2Foo);             t2.Start();             Thread.Sleep(3000);             _menuRestEvent.Set();             //_menuRestEvent.Reset();                    }        void Thread1Foo()         {             _menuRestEvent.WaitOne();             MessageBox.Show("t1 step1 end");             //睡1S,用於等待主線程_menuRestEvent.Reset();             Thread.Sleep(1000);             _menuRestEvent.WaitOne();             MessageBox.Show("t1 step2 end");         }        void Thread2Foo()         {             _menuRestEvent.WaitOne();             MessageBox.Show("t2 step1 end");             //睡1S,用於等待主線程_menuRestEvent.Reset();             Thread.Sleep(1000);             _menuRestEvent.WaitOne();             MessageBox.Show("t2 step2 end");         }     在程式碼片段4中,我們對//_menuRestEvent.Reset()進行了注釋,也就是說, _menuRestEvent.Set()後,線程的狀態就是true狀態的,程式啟動並執行結果是"t1 step1 end"、"t1 step2 end"、"t1 step2 end"、"t2 step2 end"在3秒之後全部彈出。    而如果我們將//_menuRestEvent.Reset()的注釋去掉,會發現"t1 step2 end"和"t2 step2 end"永遠不會彈出。除非我們在主線程中再次對_menuRestEvent進行Set()。

  

C#AutoResetEvent和ManualResetEvent的區別

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.