當前位置:才華齋>IT認證>ACCP>

C# AutoResetEvent的使用

ACCP 閱讀(2.42W)

AutoResetEvent 允許執行緒通過發訊號互相通訊。通常,此通訊涉及執行緒需要獨佔訪問的資源。執行緒通過呼叫 AutoResetEvent 上的 WaitOne 來等待訊號。如果 AutoResetEvent 處於非終止狀態,則該執行緒阻塞,並等待當前控制資源的執行緒

C# 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。