C#线程同步手动重置事件——ManualResetEvent
和AutoResetEvent类的区别是,Manual一旦set后不会自动reset,会放行所有waitone的线程,而autoresetevent每一次set之后只会放行一个waitone的线程,然后立即自动reset。这就是自动和手动的区别,实际上说的是自动reset和手动reset。
这里就贴一段翻译注释的msdn官方代码吧。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace myTest { class Program { private static ManualResetEvent mre = new ManualResetEvent(false); static void Main(string[] args) { Console.WriteLine("\n开启3个被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("\n当所有的线程都start后,按下回车键以运行ManualResetEvent的set方法" + "\n来释放所有线程的阻塞状态.\n"); Console.ReadLine(); mre.Set(); Thread.Sleep(500); Console.WriteLine("\n一旦ManualResetEvent对象收到了set的信号,后面再调用WaitOne()方法的线程" + "\n就不会被阻塞了.按下回车键查看结果.\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("\n按下回车键调用 Reset(), 这样后边再启动的线程调用waitone()时又会被阻塞了" ); Console.ReadLine(); mre.Reset(); // 启动一个被ManualResetEvent阻塞的线程 Thread t5 = new Thread(ThreadProc); t5.Name = "Thread_5"; t5.Start(); Thread.Sleep(500); Console.WriteLine("\n按下Enter键调用 Set() 并结束此次演示."); Console.ReadLine(); mre.Set(); Console.ReadLine(); } private static void ThreadProc() { string name = Thread.CurrentThread.Name; Console.WriteLine(name + " 启动并调用 mre.WaitOne()"); mre.WaitOne(); Console.WriteLine(name + " 退出."); } } }