gpt4 book ai didi

c# - 在 EventHandler 中尝试 Set() 时,如何检查 ManualResetEvent 是否已被处置?

转载 作者:可可西里 更新时间:2023-11-01 08:21:03 26 4
gpt4 key购买 nike

我有以下设计模式:

    var myObjectWithEvents = new ObjectWithEvents();
using (var mre = new ManualResetEvent(false)) {
var onEvent = new EventHandler<EventArgs>((sender, e) => { mre.Set(); });
try {
myObjectWithEvents.OnEvent += onEvent;
var task = Task.Factory.StartNew(() => {
myObjectWithEvents.DoSomethingThatShouldRaiseAnEvent();
});
var timedOut = !mre.WaitOne(10000);
}
finally {
myObjectWithEvents.OnEvent -= onEvent;
}
}

我的问题是,如果在 WaitOne 超时并且执行步出 using block 后引发 OnEvent,则本地 onEvent 事件处理程序仍将被调用并尝试设置已被释放的 ManualResetEvent mre,即使 onEvent 应该已从 OnEvent 中注销。

一个简单的解决方法是检查 mre 是否已经被处理,但不幸的是没有这样的字段,我相信将 mre.Set() 包装在一个try catch block 忽略异常是不干净的,因为异常可能会非常频繁地发生。

在不遇到此类问题的情况下,您认为实现上述代码模式的目的(即等待引发事件)的最佳和最简单的方法是什么?

编辑:感谢您的回答,我创建了以下扩展并将 mre.Set() 替换为 mre.TrySet():

    public static void TrySet(this ManualResetEvent mre) {
if (!mre.SafeWaitHandle.IsClosed) mre.Set();
}

最佳答案

ManualResetEvent.SafeWaitHandle.IsClosed

看起来很奇怪,但是 dispose 所做的唯一一件事就是关闭 safeHandler,这是 dispose 打算...的唯一对象......

SafeWaitHandle 的 Dispose,将此属性从 False 更改为 True。

关于c# - 在 EventHandler 中尝试 Set() 时,如何检查 ManualResetEvent 是否已被处置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9004225/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com