当前位置: 首页 > news >正文

C# EventWaitHandle

EventWaitHandle 是 .NET 中用于线程同步的一个核心基类,它封装了 Windows 操作系统中的 “事件内核对象(Event Kernel Object)”,用于在多个线程之间传递信号、协调执行顺序。

AutoResetEventManualResetEvent 都是 EventWaitHandle 的派生类。理解 EventWaitHandle 有助于你更灵活地使用或自定义事件同步机制。


🧱 一、什么是 EventWaitHandle?

EventWaitHandle 表示一个“线程同步事件”,它有两种状态:

  • 非信号状态(nonsignaled):调用 WaitOne() 的线程会被阻塞。
  • 信号状态(signaled):调用 WaitOne() 的线程可以立即继续执行。

你可以通过 Set() 将其置为信号状态,通过 Reset() 置为非信号状态。


🔁 二、EventWaitHandle 的两种模式

EventWaitHandle 的行为由构造函数中的 EventResetMode 枚举决定:

public enum EventResetMode
{AutoReset,   // 自动重置模式 → 相当于 AutoResetEventManualReset  // 手动重置模式 → 相当于 ManualResetEvent
}

✅ 创建方式:

// 等价于 new AutoResetEvent(false)
var auto = new EventWaitHandle(initialState: false, mode: EventResetMode.AutoReset
);// 等价于 new ManualResetEvent(false)
var manual = new EventWaitHandle(initialState: false, mode: EventResetMode.ManualReset
);

💡 所以:
AutoResetEventnew EventWaitHandle(false, EventResetMode.AutoReset)
ManualResetEventnew EventWaitHandle(false, EventResetMode.ManualReset)


🛠 三、核心方法与属性

方法/属性说明
WaitOne()阻塞当前线程,直到事件变为信号状态
WaitOne(int timeout)带超时的等待(毫秒),超时返回 false
Set()将事件设为信号状态
Reset()将事件设为非信号状态
Close() / Dispose()释放底层操作系统句柄(推荐 using 或显式释放)

🔐 四、底层原理(Windows 内核)

  • EventWaitHandle 封装了 Windows API 中的 CreateEvent 内核对象。
  • 它是一个 内核模式同步对象(Kernel-mode synchronization object),因此:
    • 可跨进程共享(通过命名事件)
    • 性能开销比用户模式同步(如 MonitorSpinLock)大
    • 但功能更强(支持超时、跨进程等)

🌐 五、高级用法:命名事件(跨进程同步)

EventWaitHandle 支持命名事件,可用于不同进程间的线程同步

示例:确保程序单实例运行

static void Main()
{bool createdNew;using var mutex = new Mutex(true, "MyAppSingletonMutex", out createdNew);// 但也可以用命名 EventWaitHandle 实现类似逻辑using var eventHandle = new EventWaitHandle(false,EventResetMode.ManualReset,"Global\\MyAppReadyEvent", // 名称,"Global\" 表示全局命名空间out createdNew);if (createdNew){Console.WriteLine("我是第一个实例,正在初始化...");Thread.Sleep(3000);eventHandle.Set(); // 通知其他实例我已就绪}else{Console.WriteLine("已有实例运行,等待其就绪...");eventHandle.WaitOne(); // 等待第一个实例发出信号Console.WriteLine("主实例已就绪,继续执行...");}
}

⚠️ 注意:

  • 名称在系统范围内必须唯一
  • 在 Windows 上,普通用户默认只能访问 Local\ 命名空间;需要管理员权限才能使用 Global\
  • Linux/macOS(.NET Core+)也支持命名事件,但实现依赖于平台(如 POSIX 命名信号量)

🔄 六、与 WaitHandle.WaitAny / WaitAll 配合使用

EventWaitHandle 继承自 WaitHandle,因此可以和 WaitHandle.WaitAnyWaitHandle.WaitAll 一起使用,实现多事件等待

示例:等待多个任务中的任意一个完成

var event1 = new EventWaitHandle(false, EventResetMode.AutoReset);
var event2 = new EventWaitHandle(false, EventResetMode.AutoReset);
var events = new WaitHandle[] { event1, event2 };// 启动两个任务
Task.Run(() => {Thread.Sleep(1000);event1.Set();
});Task.Run(() => {Thread.Sleep(2000);event2.Set();
});// 等待任意一个事件触发
int index = WaitHandle.WaitAny(events);
Console.WriteLine($"事件 {index} 先完成!");

✅ 这在异步协调、超时控制、多条件触发等场景非常有用。


⚖️ 七、性能与适用场景建议

场景推荐方案
简单线程唤醒(单次)AutoResetEventEventWaitHandle(AutoReset)
广播唤醒所有线程ManualResetEvent
跨进程同步命名的 EventWaitHandle
高性能、低延迟(同进程)优先考虑 Monitor.Wait/PulseTaskCompletionSourceSemaphoreSlim
需要等待多个事件WaitHandle.WaitAny / WaitAll + EventWaitHandle

❗ 注意:由于 EventWaitHandle 涉及内核切换,每秒数千次以上的高频同步应避免使用它


🧪 八、完整示例:生产者-消费者(使用 EventWaitHandle)

class Program
{static EventWaitHandle _itemAdded = new EventWaitHandle(false, EventResetMode.AutoReset);static Queue<int> _queue = new Queue<int>();static readonly object _lock = new object();static void Main(){new Thread(Consumer).Start();new Thread(Producer).Start();Console.ReadKey();}static void Producer(){for (int i = 0; i < 5; i++){lock (_lock){_queue.Enqueue(i);Console.WriteLine($"生产: {i}");}_itemAdded.Set(); // 通知消费者Thread.Sleep(500);}}static void Consumer(){while (true){_itemAdded.WaitOne(); // 等待有新项lock (_lock){if (_queue.Count > 0){int item = _queue.Dequeue();Console.WriteLine($"消费: {item}");}}}}
}

✅ 九、总结

特性说明
本质封装 Windows 事件内核对象的 .NET 类
两种模式AutoReset(过一人自动关) vs ManualReset(需手动关)
继承关系EventWaitHandleWaitHandleMarshalByRefObjectobject
关键能力线程阻塞/唤醒、超时控制、跨进程同步、多事件等待
替代方案高频场景用 SemaphoreSlimTaskChannels 等更现代的并发原语

💡 记住
EventWaitHandle 是底层而强大的同步工具,适合中低频、需要精确控制或跨进程的场景。
日常开发中,若无特殊需求,优先考虑更高层的抽象(如 Taskasync/awaitBlockingCollection)。

http://www.dtcms.com/a/583050.html

相关文章:

  • 如何运营网站制作企业官网哪家好
  • 十堰哪家网站制作公司技术好企点登录
  • 七彩喜智慧康养:用科技的温度,重新定义“老有所依”
  • Tomcat8版本升级教程
  • 2026商业航天展,解锁商业航天产业全链条创新图景
  • wordpress演示站功能基于WordPress开发
  • 解决蛋白质构象异质性的原子级建模挑战!David Baker团队PLACER框架解析
  • 兴平住房和城乡建设局门户网站wordpress 表单校验
  • wordpress发布文章到指定页面网站怎么关键字优化
  • 做农资的网站公司名字大全免费测吉凶
  • 岳阳市交通建设投资公司门户网站wordpress主题汉化中文
  • 安防公司做网站图片湖南省郴州市十大旅游景点排行榜
  • 博物馆门户网站建设目标seo如何快速出排名
  • 影视网站的设计与实现网络服务提供者不履行法律行政法规规定的
  • 官方网站做背景墙厂家网站的开发方式
  • onethink做的企业网站在县城做商城网站
  • 【智能体-DeepMiner】利用滑动窗口 提高多轮交互能力
  • [尚庭公寓P159-169][结束][第7天]
  • 做网站用哪个编程语言wordpress多用户商城
  • 门户网站框架下载wordpress 果蔬论坛
  • C++并查集
  • Linux开发:readlink命令读取软连接指向的文件
  • 行业协会网站建设的方案郑州网站建站模板
  • 网站的设计方案wordpress做门户怎么样
  • Python 图片转字符画
  • ClamAV 在 CentOS7 上的离线安装与使用指南
  • 广东自助建站网站可以免费注册网站
  • 个人空间网站建设迅速上排名网站优化
  • 怎么检查网站死链中型网站
  • 网站平均停留时间常德烟机网站