AutoResetEvent 允許執行緒通過發訊號互相通訊。通常,此通訊涉及執行緒需要獨佔訪問的資源。執行緒通過呼叫 AutoResetEvent 上的 WaitOne 來等待訊號。如果 AutoResetEvent 處於非終止狀態,則該執行緒阻塞,並等待當前控制資源的執行緒
通過呼叫 Set 發出資源可用的訊號。
呼叫 Set 向 AutoResetEvent 發訊號以釋放等待執行緒。AutoResetEvent 將保持終止狀態,直到一個正在等待的執行緒被釋放,然後自動返回非終止狀態。如果沒有任何執行緒在等待,則狀態將無限期地保持為終止狀態。
可以通過將一個布林值傳遞給建構函式來控制 AutoResetEvent 的初始狀態,如果初始狀態為終止狀態,則為 true;否則為 false。
通俗的來講只有等()成功執行後,One()才能夠獲得執行機會;Set是發訊號,WaitOne是等待訊號,只有發了訊號,
等待的才會執行。如果不發的話,WaitOne後面的'程式就永遠不會執行。下面我們來舉一個例子:我去書店買書,當我選中一本書後我會去收費處付錢,
付好錢後再去倉庫取書。這個順序不能顛倒,我作為主執行緒,收費處和倉庫做兩個輔助執行緒,程式碼如下:
using System;
using ;
using vities;
using ements;
using ading;
namespace CaryAREDemo
{
class Me
{
const int numIterations = 550;
static AutoResetEvent myResetEvent = new AutoResetEvent(false);
static AutoResetEvent ChangeEvent = new AutoResetEvent(false);
//static ManualResetEvent myResetEvent = new ManualResetEvent(false);
//static ManualResetEvent ChangeEvent = new ManualResetEvent(false);
static int number; //這是關鍵資源
static void Main()
{
Thread payMoneyThread = new Thread(new ThreadStart(PayMoneyProc));
= "付錢執行緒";
Thread getBookThread = new Thread(new ThreadStart(GetBookProc));
= "取書執行緒";
t();
t();
for (int i = 1; i <= numIterations; i++)
{
eLine("買書執行緒:數量{0}", i);
number = i;
//Signal that a value has been written.
();
();
p(0);
}
t();
t();
}
static void PayMoneyProc()
{
while (true)
{
One();
//t();
eLine("{0}:數量{1}", , number);
}
}
static void GetBookProc()
{
while (true)
{
One();
// t();
eLine("{0}:數量{1}", , number);
eLine("------------------------------------------");
p(0);
}
}
}
}
執行結果如下:
AutoResetEvent與ManualResetEvent的區別
他們的用法宣告都很類似,Set方法將訊號置為傳送狀態 Reset方法將訊號置為不傳送狀態WaitOne等待訊號的傳送。其實,從名字就可以看出一個手動,
一個自動,這個手動和自動實際指的是在Reset方法的處理上,如下面例子:
public AutoResetEvent autoevent=new AutoResetEvent(true);
public ManualResetEvent manualevent=new ManualResetEvent(true);
預設訊號都處於傳送狀態,
One();
One();
如果 某個執行緒呼叫上面該方法,則當訊號處於傳送狀態時,該執行緒會得到訊號,得以繼續執行。差別就在呼叫後,One()每次只允許一個執行緒
進入,當某個執行緒得到訊號(也就是有其他執行緒呼叫了()方法後)後,autoevent會自動又將訊號置為不傳送狀態,則其他呼叫WaitOne的執行緒只
有繼續等待.也就是說,autoevent一次只喚醒一個執行緒。而manualevent則可以喚醒多個執行緒,因為當某個執行緒呼叫了set方法後,其他呼叫waitone的執行緒
獲得訊號得以繼續執行,而manualevent不會自動將訊號置為不傳送.也就是說,除非手工呼叫了t().方法,則manualevent將一直保持有訊號狀態,manualevent也就可以同時喚醒多個執行緒繼續執行。如果上面的程式換成ManualResetEvent的話,就需要在waitone後面做下reset。