ManualResetEvent 与 AutoResetEvent
1. ManualResetEvnet
var mevent = new ManualResetEvent(false); Task.Factory.StartNew(() => { mevent.WaitOne(); MessageBox.Show("Task1"); }); Task.Factory.StartNew(() => { mevent.WaitOne(); MessageBox.Show("Task2"); }); Thread.Sleep(2000); mevent.Set();
之后 mevent.Set() 把状态设置为true , 此时WaitOne就可以执行完毕。
此时状态一直是true, 只有Reset才变为false。
注意,当 ManualResetEvent Set()后,会使得所有等待的 WaitOne 执行完毕。
上面的代码 Task1 和 Task2 都将继续执行下去
2.AutoResetEvent
他不但可以自动Reset, 而且,当他Set后,自动立刻再次变为 false 状态。
很多地方没有好好说明 什么叫 “立刻” 。我们稍后解释。
var aevent = new AutoResetEvent(false); Task.Factory.StartNew(() => { aevent.WaitOne(); MessageBox.Show("Task1"); }); Task.Factory.StartNew(() => { aevent.WaitOne(); MessageBox.Show("Task2"); }); Thread.Sleep(2000); aevent.Set();上面的代码, 当 aevent.Set() 后 只能使一个WaitOne完成
一般是 Task1
3. 解释一下 “立刻” 的含义
为什么 ManualResetEvent 可以释放所有的 WaitOne , 而AutoResetEvent 只能释放一个?
我们可以通过以下代码,让 ManualResetEvent也只释放一个 WaitOne , 类似AutoResetEvent
var mevent = new ManualResetEvent(false); Task.Factory.StartNew(() => { lock (mevent) { mevent.WaitOne(); mevent.Reset(); } MessageBox.Show("Task1"); }); Task.Factory.StartNew(() => { lock (mevent) { mevent.WaitOne(); mevent.Reset(); } MessageBox.Show("Task2"); }); Thread.Sleep(2000); mevent.Set(); }
上面的代码通过 lock 使得 mevent立刻Reset 达到了 AutoResetEvent 的效果
从这里也可以看到 “立刻” 的含义其实是 在释放完一个 WaitOne(或者没有任何可以释放的对象)后,立刻Reset
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能