我們線上程編程的時候往往會涉及到線程的通信,通過信號的接受來進行線程是否阻塞的操作。 AutoResetEvent 允許線程通過發信號互相通信。通常,此通信涉及線程需要獨占訪問的資源。 AutoResetEvent 的方法有很多,具體方法和擴展方法請詳見AutoResetEvent類,最常用方法中就 ...
我們線上程編程的時候往往會涉及到線程的通信,通過信號的接受來進行線程是否阻塞的操作。
AutoResetEvent 允許線程通過發信號互相通信。通常,此通信涉及線程需要獨占訪問的資源。
AutoResetEvent 的方法有很多,具體方法和擴展方法請詳見AutoResetEvent類,最常用方法中就有Set()和WaitOne()。
線程通過調用 AutoResetEvent 上的 WaitOne 來等待信號。如果 AutoResetEvent 處於非終止狀態,則該線程阻塞,並等待當前控制資源的線程通過調用 Set 發出資源可用的信號。AutoResetEvent 的非終止狀態可以通過構造函數在設置:
static AutoResetEvent myResetEvent = new AutoResetEvent(false);這裡構造函數中的參數false就代表該狀態為非終止狀態,相反若為true則為終止狀態。
通俗的來講只有等myResetEven.Set()成功運行後,myResetEven.WaitOne()才能夠獲得運行機會;Set是發信號,WaitOne是等待信號,只有發了信號,
等待的才會執行。如果不發的話,WaitOne後面的程式就永遠不會執行。下麵我們來舉一個例子:public class Program { static AutoResetEvent myResetEvent = new AutoResetEvent(false); const int cycleNum = 5; static void Main(string[] args) { Thread td = new Thread(new ThreadStart(sqrt)); td.Name = "線程一"; td.Start(); Console.ReadKey(); } /// <summary> /// 計算平方 /// </summary> /// <param name="i"></param> public static void sqrt() { myResetEvent.WaitOne(); Console.WriteLine(DateTime.Now.ToShortTimeString() + "線程一執行"); Thread.Sleep(500); } }
上面例子中一開始非終止狀態,當遇到WaitOne()方法時則會阻塞線程,在沒有set()時將一直處於阻塞狀態,運行結果如下:
接下來我們在主函數中執行Set()方法來解放被阻塞的線程:
public class Program { static AutoResetEvent myResetEvent = new AutoResetEvent(false); const int cycleNum = 5; static void Main(string[] args) { Thread td = new Thread(new ThreadStart(sqrt)); td.Name = "線程一"; td.Start(); myResetEvent.Set();//WaitOne方法阻塞,Set()方法執行後則繼續執行 Console.ReadKey(); } /// <summary> /// 計算平方 /// </summary> /// <param name="i"></param> public static void sqrt() { myResetEvent.WaitOne(); Console.WriteLine(DateTime.Now.ToShortTimeString() + "線程一執行"); Thread.Sleep(500); } }運行結果如下:
既然說到了AutoResetEvent,就不得不說ManualResetEvent,這兩個方法幾乎相同,不同的地方就在於AutoResetEvent的WaitOne()方法執行後會自動又將信號置為不發送狀態也就是阻塞狀態,當再次遇到WaitOne()方法是又會被阻塞,而AutoResetEvent則不會,只要線程處於非阻塞狀態則無論遇到多少次WaitOne()方法都不會被阻塞,除非調用ReSet()方法來手動阻塞線程。這裡就不截圖運行結果了,有興趣的朋友可以自己試一試。
本博客不保證所有信息全部正確,有錯誤還希望指出。
作者:依封劍白出處:學習:多線程之AutoResetEvent
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。如有問題或建議,請多多賜教,非常感謝。