我遇到一种情况,我正在创建许多IDisposable对象,每个对象都封装了一个EventWaitHandle实例,以便我的应用程序的各个感兴趣的部分都可以等待它们。此实例不能由其所有者对象之外的任何代码直接访问。它只能通过包装程序调用间接访问。

对象发出信号后,它不再有用,因此由中央管理器对象处理并从其引用列表中抛弃。

现在的问题是,封装的EventWaitHandle怎么办?自然,也应该尽快处理它,以防止我的应用泄漏操作系统句柄。

但是,在事件的所有者对象发出信号后立即同步执行此操作是否安全?如果仍有线程仍在等待释放(即阻塞对WaitOne()的调用内),会发生什么?

这里推荐的方法是什么?

最佳答案

我想是时候根据我自己的发现来结束这一话题了。

我在文档中找不到任何直接指南,但决定遵循从Raymond Chen博客中提取的信息。在他的帖子中(我忘记了确切的链接),他提到Win32 API规则指示事件的句柄必须在等待期间保持有效。在不受管理的世界中,这意味着事件的至少一个句柄必须保持打开状态。

AFAIU是.NET的实现,它在后台使用Win32 API,每个EventWaitHandle实例对应一个单独的非托管事件。当EventWaitHandle.Dispose()关闭基础非托管事件的唯一句柄时,这实际上使事件实例无效。

简而言之,正确的方法似乎是建立一个并行的基础结构,事件发布者可以通过该基础结构通知潜在的听众事件将很快消失。然后,发布者必须等到所有侦听器都“取消订阅”(即停止等待),然后才能继续Dispose()事件实例。

记账很多,但最终看来似乎是正确的。希望这也可以帮助别人清除事情。

08-06 12:45