近来在学习Eugene Agafonov编写的《C#多线程编程实战》(译),做些笔记也顺便分享一下^-^
using System; using System.Threading; namespace ManualResetEventSlim_Test { class Program { static void Main(string[] args) { var t1 = new Thread(() => TravelThroughGates("Thread1", 5)); var t2 = new Thread(() => TravelThroughGates("Thread2", 6)); var t3 = new Thread(() => TravelThroughGates("Thread3", 12)); t1.Start(); t2.Start(); t3.Start(); Thread.Sleep(TimeSpan.FromSeconds(6)); Console.WriteLine("The gates are now open!"); _mainEvent.Set(); Thread.Sleep(TimeSpan.FromSeconds(2)); _mainEvent.Reset(); Console.WriteLine("The gates have been closed!"); Thread.Sleep(TimeSpan.FromSeconds(10)); Console.WriteLine("The gates are now open for the second time!"); _mainEvent.Set(); Thread.Sleep(TimeSpan.FromSeconds(2)); Console.WriteLine("The gates have been closed!"); _mainEvent.Reset(); Console.ReadKey(); } static ManualResetEventSlim _mainEvent = new ManualResetEventSlim(false); static void TravelThroughGates(string threadName,int seconds) { Console.WriteLine("{0} false to sleep", threadName); Thread.Sleep(TimeSpan.FromSeconds(seconds)); Console.WriteLine("{0} waits for the gates to open!", threadName); _mainEvent.Wait(); Console.WriteLine("{0} enters the gates!", threadName); } } }
程序运行结果如下
当主程序启动时,首先创建了ManualResetEventSlim类的一个实例。然后启动了三个线程,等待事件信号通知它们继续执行。
ManualResetEventSlim的整个工作方法有点像人群通过大门,AutoResetEvent事件像一个旋转门,一次只允许一人通过。ManualResetEventSlim是ManualResetEvent的混合版本,一直保持大门敞开直到手动调用Reset方法。当调用_mainEvent.Set时,相当于打开了大门从而允许准备好的线程接收信号并继续工作。然而线程3还处于睡眠状态,没有赶上时间。当调用_mainEvent.Reset相当于关闭了大门。最后一个线程已经准备好要执行,但是不得不等待下一个信号。