在调用.Set之后直接对EventWaitHandle调用.Close (.Dispose)安全吗?

3
我有一个线程正在等待一个EventWaitHandle(自动重置事件):
AutoResetEvent.WaitOne();

我有另一个线程在发信号让第一个线程继续执行。

AutoResetEvent.Set();
AutoResetEvent.Close();

在调用.Set之后直接调用.Close是否安全,换句话说,在销毁AutoResetEvent之前等待的线程是否已经继续执行是有保证的吗?


1
Close文档中写道:“一旦调用此方法,对当前实例的引用将导致未定义的行为。”无论是新引用还是现有引用(例如您对WaitOne的调用),都没有明确说明。但我不想尝试它...为什么不由等待方关闭/处理它呢? - James Thorpe
因为等待是可选的,所以如果等待没有完成,它就不会被释放... - Edwin
1个回答

2

如果按照您提问中描述的方式运行,那么是安全的。如果您知道在调用 set 时所有线程都已经处于等待状态,那么这些线程将被通知并且一切都会很好,因为在调用 set 返回之前,所有等待的线程都得到保证将被释放。

然而,如果由于某种原因存在竞争情况,并且在线程开始等待之前调用了 set 和 close,则在尝试等待时会出现异常。因此,在实践中最好避免使用此模式。我个人认为如此。


我认为你永远无法知道线程正在等待。它们可能在进入等待之前的1个指令被取消调度,其他线程可能无法察觉。 - usr
谢谢您的回复。所以我放弃了这个模式。我找到了一个AutoResetEvent的托管实现,我可能会尝试一下:http://www.codeproject.com/Articles/244638/Managed-Thread-Synchronization - Edwin
@usr 没错,这就是为什么我认为这是一个不可靠的模式。我对这里的情况了解不够,无法推荐其他解决方案,但可以实现一些简单的线程安全倒计时,在线程信号和关闭处理程序检查计数之前关闭处理程序,以确保所有消费者完成其任务。或者简单地反转依赖关系... - Niclas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接