代码之家  ›  专栏  ›  技术社区  ›  Allen Rice 0x6A75616E

我的EventWaitHandle说“访问路径被拒绝”,但不是这样

  •  14
  • Allen Rice 0x6A75616E  · 技术社区  · 16 年前

    我有一个 EventWaitHandle 我创建的,然后关闭的。当我尝试用 this ctor EventWaitHandle 很好。有了下面(由我)发布的答案,我能够成功地打电话给你 EventWaitHandle.OpenExisting EventWaitHandle out parameter , createdNew 是为了什么?


    我在同一台服务器上有以下体系结构,一个windows服务和一个web服务。web服务通过打开并设置windows服务正在等待的等待句柄来告诉windows服务它必须执行工作。

    更新:引发异常&发行日志

    我在web服务工作时重新启动了windows服务,希望引起这个问题,它确实做到了!一些类名因公司匿名而被审查

    12:00:41,250 [7] - Stopping execution due to a ThreadAbortException
    System.Threading.ThreadAbortException: Thread was being aborted.
       at System.Threading.Thread.SleepInternal(Int32 millisecondsTimeout)
       at OurCompany.OurProduct.MyClass.MyClassCore.MonitorRequests()
    
    12:00:41,328 [7] - Closing Event Wait Handle
    12:00:41,328 [7] - Finally block reached
    
    
    12:00:42,781 [6] - Application Start
    12:00:43,031 [6] - Creating EventWaitHandle: Global\OurCompany.OurProduct.MyClass.EventWaitHandle
    12:00:43,031 [6] - Creating EventWaitHandle with the security entity name of : Everyone
    
    12:00:43,078 [6] - Unhandled Exception 
    System.UnauthorizedAccessException: Access to the path 'Global\OurCompany.OurProduct.MyClass.EventWaitHandle' is denied.
       at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
       at System.Threading.EventWaitHandle..ctor(Boolean initialState, EventResetMode mode, String name, Boolean& createdNew, EventWaitHandleSecurity eventSecurity)
       at OurCompany.OurProduct.MyClassLibrary.EventWaitHandleFactory.GetNewWaitHandle(String handleName, String securityEntityName, Boolean& created)
       at OurCompany.OurProduct.MyClassLibrary.EventWaitHandleFactory.GetNewEventWaitHandle()
       at OurCompany.OurProduct.MyClass.MyClassCore..ctor()
    

    • 11:53:09937:web服务上打开现有等待句柄的最后一个线程已完成其工作(与客户端的终止连接相同)

    • 12:00:41250:windows服务停止

    • 12:00:42781:windows服务启动

    • 12:02:00000:我尝试重新启动windows服务,相同的异常

    • 12:36:57328:在任意等待36分钟后,我能够在不完全重新启动系统的情况下启动windows服务。


    初始化:

    // I ran into security issues so I open the global EWH
    //    and grant access to Everyone
    var ewhSecurity = new EventWaitHandleSecurity();
    
    ewhSecurity.AddAccessRule(
     new EventWaitHandleAccessRule(
      "Everyone",
      EventWaitHandleRights.Synchronize | EventWaitHandleRights.Modify,
      AccessControlType.Allow));
    
    this.ewh = new EventWaitHandle(
     false,
     EventResetMode.AutoReset,
     @"Global\OurCompany.OurProduct.MyClass.EventWaitHandle",
     out created,
     ewhSecurity);
    
    // the variable "created" is logged
    

    // wait until the web service tells us to loop again
    this.ewh.WaitOne();
    

    处置/关闭:

    try
    {
        while (true)
        {
            // entire service logic here
        }
    }
    catch (Exception e)
    {
        // should this be in a finally, instead?
        if (this.ewh != null)
        {
            this.ewh.Close();
        }
    }
    

    Web服务代码

    初始化:

    // NOTE: the wait handle is a member variable on the web service
    this.existing_ewh = EventWaitHandle.OpenExisting(
        @"Global\OurCompany.OurProduct.MyClass.EventWaitHandle");
    

    利用:

    // wake up the windows service
    this.existing_ewh.Set();
    

    EventWaitHandle EventWaitHandle


    回想起来,我应该把 Close() 那是在 catch 一块,一块 finally

    不管怎么说,有人能看出我到底做错了什么吗?将结束语句放在finally块中是否至关重要?我是否需要手动控制系统 关闭() existing_ewh 在web服务上?

    标准物质

    2 回复  |  直到 16 年前
        1
  •  12
  •   Ofer Zelig Tom    12 年前

    EventWaitHandle.OpenExisting(
        @"Global\OurCompany.OurProduct.MyClass.EventWaitHandle",
        EventWaitHandleRights.Synchronize | EventWaitHandleRights.Modify);
    

    注:如有反馈,我将不胜感激。这是一个潜在的答案,所以我在回答我自己的问题,再次,大量的评论是非常受欢迎的!

    注2:令人惊讶的是 EventWaitHandleRights.FullControl 而不是上面的标志( Synchronize Modify

        2
  •  1
  •   Sergey Podobry    16 年前

    MSDN说:

    即使eventSecurity拒绝或未能授予当前用户某些访问权限,调用方也可以完全控制新创建的EventWaitHandle对象。

    您的服务无权通过EventWaitHandle构造函数获取现有事件(未指定EventWaitHandlerRights.FullControl。并且您的命名事件在其上打开句柄时存在。)您可以使用EventWaitHandle.OpenExisting打开现有事件。