2011-10-12 28 views
2
using System; 
using System.Threading; 

public class Example 
{ 
    // mre is used to block and release threads manually. It is 
    // created in the unsignaled state. 
    private static ManualResetEvent mre = new ManualResetEvent(false); 

    static void Main() 
    { 
     Console.WriteLine("\nStart 3 named threads that block on a ManualResetEvent:\n"); 

     for(int i = 0; i <= 2; i++) 
     { 
      Thread t = new Thread(ThreadProc); 
      t.Name = "Thread_" + i; 
      t.Start(); 
     } 

     Thread.Sleep(500); 
     Console.WriteLine("\nWhen all three threads have started, press Enter to call Set()" + 
          "\nto release all the threads.\n"); 
     Console.ReadLine(); 

     mre.Set(); 

     Thread.Sleep(500); 
     Console.WriteLine("\nWhen a ManualResetEvent is signaled, threads that call WaitOne()" + 
          "\ndo not block. Press Enter to show this.\n"); 
     Console.ReadLine(); 

     for(int i = 3; i <= 4; i++) 
     { 
      Thread t = new Thread(ThreadProc); 
      t.Name = "Thread_" + i; 
      t.Start(); 
     } 

     Thread.Sleep(500); 
     Console.WriteLine("\nPress Enter to call Reset(), so that threads once again block" + 
          "\nwhen they call WaitOne().\n"); 
     Console.ReadLine(); 

     mre.Reset(); 

     // Start a thread that waits on the ManualResetEvent. 
     Thread t5 = new Thread(ThreadProc); 
     t5.Name = "Thread_5"; 
     t5.Start(); 

     Thread.Sleep(500); 
     Console.WriteLine("\nPress Enter to call Set() and conclude the demo."); 
     Console.ReadLine(); 

     mre.Set(); 

     // If you run this example in Visual Studio, uncomment the following line: 
     //Console.ReadLine(); 
    } 

    //thread entry point 
    private static void ThreadProc() 
    { 
     string name = Thread.CurrentThread.Name; 

     Console.WriteLine(name + " starts and calls mre.WaitOne()"); 
     //wait untill signaled 
     mre.WaitOne(); 

     Console.WriteLine(name + " ends."); 
    } 
} 

我寫了一個例子來理解autoresetevent和manualresetevent。 但是當我們不得不使用Autoresetevent和manualresetevent synchornization時,還不清楚嗎? 上面是這個例子。請提供真實世界場景,我們可以使用基於事件的同步 。autoresetevent和manualresetevent

回答

3

有幾個地方使用這種東西。我個人認爲通常是寧願Monitor.Wait/Pulse,但有些時候{手動/自動} ResetEvent更有用 - 尤其是當您希望能夠在多個手柄上等待時。

,我已經看到了這個使用的兩個最明顯的情況是:

  • 生產者/消費者隊列:當隊列爲空時,消費者會等待在監視器上或者等待處理。生產者隨後會在添加物品時對監視器/手柄進行脈衝/設置,以喚醒消費者,使其知道它有工作要做。
  • 喚醒一個「睡眠」線程,讓它知道它可以退出:有一個while(!ShouldStop) { Work(); Wait(10000); }類型的循環並不罕見; 「停止」線程可以再次使等待線程喚醒注意到已經設置了「停止」標誌

這些當然是非常相似的場景,毫無疑問,還有更多的 - 但那些是我最常看到的。