关于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不会阻塞,直接释放掉所有的线程。
作者:Chuck Lu GitHub |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了