EventWaitHandle 没有在进程终止时关闭
Posted
技术标签:
【中文标题】EventWaitHandle 没有在进程终止时关闭【英文标题】:EventWaitHandle not getting closed on process kill 【发布时间】:2012-06-21 21:04:01 【问题描述】:我有一个 C# 程序,它会像这样打开一个 EventWaitHandle 以由 Windows 服务触发。
EventWaitHandle sampleEventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, "Global\\sampleEvent");
当程序现在被杀死(或由于意外错误而死)时,EventWaitHandle 没有被关闭,并且在重新启动程序时会发生以下错误:
System.UnauthorizedAccessException:对路径的访问被拒绝。 在 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.Threading.EventWaitHandle..ctor(Boolean initialState, EventResetMode mode, String name)
一分钟后,EventWaitHandle 将关闭,您可以重新启动应用程序。
任何想法如何解决这个问题?
【问题讨论】:
msdn.microsoft.com/en-us/library/… 谢谢。我认为这将解决我的问题。你知道默认的 EventWaitHandleSecurity 是什么吗? (只是出于兴趣,我想知道) 知道如何在进程终止时自动关闭 EventWaitHandle 仍然会很有趣...... 我没有。只是做了一个快速的谷歌搜索,实验看起来不像我可以立即完成的事情(但链接看起来对你很有希望)。如果我以后有时间,打算检查一下。 【参考方案1】:这是因为服务在同一个对象上打开了一个句柄。这是意料之中的,毕竟您正在使用它来实现服务和程序之间的信令。在最后一个句柄关闭之前,物理底层 Windows 命名对象不会从全局命名空间中删除。
因此,在此情况下获得异常会为您提供真正的问题诊断,该服务使用了错误的句柄,并且在您重新启动程序时永远无法与您通信。很难猜一分钟后如何解决这个问题,我不得不假设该服务会定期调用 OpenExisting()。
解决方案很简单:它应该是创建等待句柄的服务,并且您的 UI 程序应该调用 OpenExisting()。该事件现在始终存在,至少只要服务还活着。如果没有,那么 OpenExisting() 会通过 WaitHandleCannotBeOpenedException 为您提供出色的诊断
【讨论】:
谢谢。由于您的评论,我发现了问题所在。我没有在我的 Windows 服务中关闭 EventWaitHandle,这就是为什么它在关闭 GUI 后仍然存在的原因。 这没关系,除非您的服务终止或崩溃。您可能会遇到事件句柄是孤立的并且永远不会设置的情况。以上是关于EventWaitHandle 没有在进程终止时关闭的主要内容,如果未能解决你的问题,请参考以下文章
在托管进程中使用 EventWaitHandle 和在非托管进程中使用 WaitForSingleObject 进行跨进程同步