关于AutoResetEvent 和ManualResetEvent
在公司的代码里面看到这两个类的使用了,第一次去msdn上的时候,看的一头雾水(关键是没有找对方法)
http://www.cnblogs.com/qingyun163/archive/2013/01/05/2846633.html 这篇博客应该会有些帮助的
这次看的比较仔细,懂得看一个类的时候,可以去找它的父类。
发现AutoResetEvent 和ManualResetEvent 全部都继承自EventWaitHandle类
EventWaitHandle中有介绍EventResetMode 这个枚举类型
// 摘要: // 指示在接收信号后是自动重置 System.Threading.EventWaitHandle 还是手动重置。 [ComVisible(false)] public enum EventResetMode { // 摘要: // 当终止时,System.Threading.EventWaitHandle 在释放一个线程后自动重置。如果没有等待的线程,System.Threading.EventWaitHandle // 将保持终止状态直到一个线程阻止,并在释放此线程后重置。 AutoReset = 0, // // 摘要: // 当终止时,System.Threading.EventWaitHandle 释放所有等待的线程,并在手动重置前保持终止状态。 ManualReset = 1, }
EventResetMode 枚举的代码示例
using System; using System.Threading; namespace MyEventResetMode { class Program { /// <summary> /// EventWaitHandle变量 可以赋值AutoReset和ManualReset /// </summary> private static EventWaitHandle ewh; /// <summary> /// 线程的计数器 在进入线程后加1 释放线程后减1 /// </summary> private static long threadCount = 0; /// <summary> /// 让主线程阻塞的 EventWaitHandle 到所有开辟出来的线程全部被释放 /// </summary> private static EventWaitHandle clearCount = new EventWaitHandle(false, EventResetMode.AutoReset); static void Main(string[] args) { //创建一个AutoReset类型的EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.AutoReset); //创建5个线程,将i作为参数传递,以识别不同的线程 for (int i = 0; i <= 4; i++) { Thread t = new Thread( new ParameterizedThreadStart(ThreadProc) ); t.Start(i); Thread.Sleep(100);//确保线程是有先后顺序的 方便后面判断AutoReset是否随机释放单个线程 } while (Interlocked.Read(ref threadCount) < 5)//等待所有的线程启动并阻塞 { Thread.Sleep(500); } Console.WriteLine(); while (Interlocked.Read(ref threadCount) > 0)//逐个释放ewh阻塞的线程 { Console.WriteLine("Press ENTER to release a waiting thread."); Console.ReadLine(); WaitHandle.SignalAndWait(ewh, clearCount);//向一个 WaitHandle 发出信号并等待另一个。 相当于下面两个语句 /* ewh.Set();//收到信号之后,随机释放一个被它阻塞的线程,其它的保持阻塞 clearCount.WaitOne();//阻塞 */ //ewh是要发出信号的WaitHandle, ewh收到信号之后,释放单个线程,然后再自动阻塞 //clearCount是要等待的WaitHandle clearCount在此等待 相当于调用了clearCount.WaitOne(); } Console.WriteLine(); //创建一个ManualReset类型的EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.ManualReset); //创建5个线程,将i作为参数传递,以识别不同的线程 for (int i = 0; i <= 4; i++) { Thread t = new Thread( new ParameterizedThreadStart(ThreadProc) ); t.Start(i); } while (Interlocked.Read(ref threadCount) < 5)//等待所有线程启动并阻塞 { Thread.Sleep(500); } Console.WriteLine("Press ENTER to release the waiting threads."); Console.ReadLine(); ewh.Set(); //一次释放所有被它阻塞的线程 Console.Read(); } public static void ThreadProc(object data) { int index = (int)data; Interlocked.Increment(ref threadCount);//计数增加 Console.WriteLine("Thread {0} blocks.", data); ewh.WaitOne();//等待ewh发出信号 Console.WriteLine("Thread {0} exits.", data); Interlocked.Decrement(ref threadCount);//计数减少 clearCount.Set();//释放主线程一次 } } }
EventWaitHandle需要注意的是,如果初始设置为false,那么就会阻塞线程。
如果初始为true,AutoReset会先释放掉等待线程中的任意一个,其他的线程仍保持阻塞。如果初始为true,ManualReset不会阻塞,直接释放掉所有的线程。