AutoResetEvent和ManualResetEvent允许线程通过发信号进行通信。
两者都有两个信号量:True和False。都通过Set()和ReSet()来设置。并且使用WaitOne()的方法阻止当前的线程。
不同的是AutoResetEvent在调用Set()把信号量释放后(信号量设置为True),然后自动返回到终止状态(信号量为False).
线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。 如果 AutoResetEvent 为非终止状态,则线程会被阻止,并等待当前控制资源的线程通过调用 Set 来通知资源可用。
调用 Set 向 AutoResetEvent 发信号以释放等待线程。 AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。 如果没有任何线程在等待,则状态将无限期地保持为终止状态。
如果当 AutoResetEvent 为终止状态时线程调用 WaitOne,则线程不会被阻止。 AutoResetEvent 将立即释放线程并返回到未触发状态。
ManualResetEvent在调用Set()后,需要手动调用ReSet()恢复到终止状态。
ManualResetEventSlim是ManualResetEvent的简化版本,是4.0新增的类。使用Wait()方法来阻止线程。
MSDN上的代码很好的解释了如何使用:
Code:
1 class Example 2 { 3 private static AutoResetEvent event_1 = new AutoResetEvent(true); 4 private static AutoResetEvent event_2 = new AutoResetEvent(false); 5 6 static void Main() 7 { 8 Console.WriteLine("Press Enter to create three threads and start them.\r\n" + 9 "The threads wait on AutoResetEvent #1, which was created\r\n" + 10 "in the signaled state, so the first thread is released.\r\n" + 11 "This puts AutoResetEvent #1 into the unsignaled state."); 12 Console.ReadLine(); 13 14 for (int i = 1; i < 4; i++) 15 { 16 Thread t = new Thread(ThreadProc); 17 t.Name = "Thread_" + i; 18 t.Start(); 19 } 20 Thread.Sleep(1000); 21 22 for (int i = 0; i < 2; i++) 23 { 24 Console.WriteLine("Press Enter to release another thread."); 25 Console.ReadLine(); 26 event_1.Set(); 27 Thread.Sleep(250); 28 } 29 30 Console.WriteLine("\r\nAll threads are now waiting on AutoResetEvent #2."); 31 for (int i = 0; i < 3; i++) 32 { 33 Console.WriteLine("Press Enter to release a thread."); 34 Console.ReadLine(); 35 event_2.Set(); 36 Thread.Sleep(250); 37 } 38 39 // Visual Studio: Uncomment the following line. 40 //Console.Readline(); 41 } 42 43 static void ThreadProc() 44 { 45 string name = Thread.CurrentThread.Name; 46 47 Console.WriteLine("{0} waits on AutoResetEvent #1.", name); 48 event_1.WaitOne(); 49 Console.WriteLine("{0} is released from AutoResetEvent #1.", name); 50 51 Console.WriteLine("{0} waits on AutoResetEvent #2.", name); 52 event_2.WaitOne(); 53 Console.WriteLine("{0} is released from AutoResetEvent #2.", name); 54 55 Console.WriteLine("{0} ends.", name); 56 } 57 }