AutoResetEvent和ManualResetEvent的區別

 摘抄函數

一、AutoResetEvent和ManualResetEvent的區別this

  終止狀態和非終止狀態:
  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來通知資源可用。it

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

AutoResetEvent只會給一個線程發送信號,而不會給多個線程發送信號。
須要同步多個線程的時候,就只能採用ManualResetEvent了。至於深層次的緣由是,AutoResetEvent在set()以後,會將線程 狀態自動置爲false,而ManualResetEvent在Set()後,線程的狀態就變爲true了,必須手動ReSet()以後,纔會從新將線程置爲false。這也就是爲何他們的名字一個爲Auto,一個爲Manual的緣由。

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");
}object

void Thread2Foo()
{
_menuRestEvent.WaitOne();
MessageBox.Show("t2 step1 end");
//睡1S,用於等待主線程_menuRestEvent.Reset();
Thread.Sleep(1000);
_menuRestEvent.WaitOne();
MessageBox.Show("t2 step2 end");
}
咱們對//_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()。

_manualResetEvent .Set();的這句話我想你們都明白了,能夠看作將IsRelease的屬性設置爲true.線程1中

_manualResetEvent.WaitOne();接收到信號後再也不阻塞線程1。在此以後的整個過程當中IsRelease的值都是true.若是

想將IsRelease的值回覆成false,就必須再調用_manualResetEvent.Reset()的方法。

若是是_autoResetEvent.set(),那麼_autoResetEvent.WaitOne()後會自動將IsRelease的值自動設置爲false。

相關文章
相關標籤/搜索