一、 ManualResetEvent ManualResetEvent是一個同步對象,可以使一個或多個線程等待另一個線程的信號,然後再同時繼續執行。它是通過兩個狀態來實現的:有信號和無信號。 以下是ManualResetEvent的各個方法的介紹: Set方法:將ManualResetEvent的 ...
一、 ManualResetEvent ManualResetEvent是一個同步對象,可以使一個或多個線程等待另一個線程的信號,然後再同時繼續執行。它是通過兩個狀態來實現的:有信號和無信號。 以下是ManualResetEvent的各個方法的介紹:
- Set方法:將ManualResetEvent的狀態設置為有信號,允許等待線程繼續執行。如果沒有線程在等待,該方法不會產生任何效果。
- Reset方法:將ManualResetEvent的狀態設置為無信號,阻止等待線程繼續執行。如果沒有線程在等待,該方法不會產生任何效果。
- WaitOne方法:阻塞當前線程,等待ManualResetEvent的狀態變為有信號。如果ManualResetEvent的狀態已經是有信號,該方法立即返回。
- WaitOne方法(帶超時參數):阻塞當前線程,等待ManualResetEvent的狀態變為有信號,或者超過指定的時間。如果ManualResetEvent的狀態已經是有信號,該方法立即返回。
- WaitAll方法(靜態方法):阻塞當前線程,等待所有指定的ManualResetEvent的狀態變為有信號。如果所有指定的ManualResetEvent的狀態已經是有信號,該方法立即返回。
- WaitAny方法(靜態方法):阻塞當前線程,等待任意一個指定的ManualResetEvent的狀態變為有信號。如果任意一個指定的ManualResetEvent的狀態已經是有信號,該方法立即返回。
- Dispose方法:釋放由ManualResetEvent占用的所有資源。一旦調用該方法,ManualResetEvent就不再可用。
static ManualResetEvent mre = new ManualResetEvent(false);//創建了一個ManualResetEvent對象,並將初始狀態設置為無信號狀態 static void Main(string[] args) { //啟動一個線程,等待信號 Thread thread = new Thread(new ThreadStart(WaitForSignal)); thread.Start(); //暫停一秒鐘 Thread.Sleep(1000); //發送信號 Console.WriteLine("Sending signal..."); mre.Set(); //將ManualResetEvent的狀態設置為有信號,允許等待線程繼續執行。如果沒有線程在等待,該方法不會產生任何效果。 // 暫停一秒鐘 Thread.Sleep(1000); // 再次發送信號 Console.WriteLine("Sending signal again..."); mre.Set(); //等待線程完成 thread.Join(); Console.WriteLine("Done"); Console.ReadKey(); } private static void WaitForSignal() { Console.WriteLine("Waiting for signal..."); mre.WaitOne(); //阻塞當前線程,等待ManualResetEvent的狀態變為有信號。如果ManualResetEvent的狀態已經是有信號,該方法立即返回。 Console.WriteLine("Signal received."); Console.WriteLine("Waiting for signal again..."); mre.Reset(); //將ManualResetEvent的狀態設置為無信號,阻止等待線程繼續執行。如果沒有線程在等待,該方法不會產生任何效果。 mre.WaitOne(); Console.WriteLine("Signal received again."); }
列印 Waiting for signal...後等待1s,
列印 Waiting for signal again...後等待1s.
二、AutoResetEvent
AutoResetEvent是一種同步機制,用於線程之間的通信。它允許一個線程等待另一個線程發出信號,然後繼續執行。AutoResetEvent只能被一個線程等待,當一個線程調用WaitOne方法時,AutoResetEvent會被設置為非終止狀態,直到另一個線程調用Set方法將其設置為終止狀態。 以下是AutoResetEvent的各個方法的介紹:- WaitOne()方法:該方法會阻塞當前線程,直到AutoResetEvent對象的狀態為終止狀態(signaled),或等待超時。如果成功等待到終止狀態,則會將AutoResetEvent對象的狀態設置為非終止狀態(nonsignaled)。
- Set()方法:該方法將AutoResetEvent對象的狀態設置為終止狀態。如果有線程正在等待這個AutoResetEvent對象,則會使其中一個線程從WaitOne()方法中返回。
- Reset()方法:該方法將AutoResetEvent對象的狀態設置為非終止狀態。如果有線程正在等待這個AutoResetEvent對象,則不會有任何影響,等待線程仍然會等待。
- Dispose()方法:該方法釋放AutoResetEvent對象占用的資源,並將AutoResetEvent對象標記為已釋放。一旦AutoResetEvent對象被釋放,任何對它的方法調用都會引發ObjectDisposedException異常。
static AutoResetEvent autoResetEvent = new AutoResetEvent(false); static void Main(string[] args) { Thread t1 = new Thread(new ThreadStart(Worker1)); t1.Start(); Thread t2 = new Thread(new ThreadStart(Worker2)); t2.Start(); Console.ReadKey(); } static void Worker1() { Console.WriteLine("Worker1 waiting for signal..."); autoResetEvent.WaitOne(); Console.WriteLine("Worker1 received signal and continuing..."); } static void Worker2() { Console.WriteLine("Worker2 sending signal..."); Thread.Sleep(1000); autoResetEvent.Set(); }
列印Worker2 sending signal...後等待1s
三、AutoResetEvent和ManualResetEvent的異同
AutoResetEvent和ManualResetEvent都是.NET Framework中的同步原語,用於協調多個線程的執行。它們的主要區別在於: 1. 觸發方式- AutoResetEvent:當某個線程調用Set方法時,只有一個等待的線程會被喚醒,並被允許繼續執行。如果有多個線程等待,那麼只有其中一個會被喚醒,其他線程仍然處於等待狀態。
- ManualResetEvent:當某個線程調用Set方法時,所有等待的線程都會被喚醒,並被允許繼續執行。
- AutoResetEvent:當某個線程被喚醒後,事件會自動重置為未觸髮狀態,其他等待的線程需要重新等待。
- ManualResetEvent:當某個線程被喚醒後,事件仍然處於觸髮狀態,其他等待的線程仍然可以通過WaitOne方法獲取事件的信號。
- AutoResetEvent:適用於需要嚴格控制線程執行順序的情況,例如生產者-消費者模式中的消費者線程需要等待生產者線程完成後才能執行。
- ManualResetEvent:適用於需要多個線程同時執行的情況,例如並行計算中的多個線程需要等待某個條件滿足後才能繼續執行。