代码之家  ›  专栏  ›  技术社区  ›  Jeremy

ManagementEventWatcher-应用程序存在时出现InvalidComObject异常

  •  2
  • Jeremy  · 技术社区  · 14 年前

    我已经建立了一个.NET库,它使用 ManagementEventWatcher 班级。我的库是一次性的,所以通常我会用using语句将它包装起来,然后 管理事件监视程序 班级将由我的图书馆处理。

    我的问题是我的库暴露在COM中,并在不使用一次性模式的VB6中使用。如果用户没有从其.NET应用程序中调用库上的dispose,或者由于VB6而无法调用,则 管理事件监视程序 全班同学将 InvalidComObjectException 从内 SinkForEventQuery.Cancel

    我无法捕获异常,因此它仍然未被处理,这是不好的。有什么办法我可以试试吗?

    System.Runtime.InteropServices.InvalidComObjectException was unhandled
      Message=COM object that has been separated from its underlying RCW cannot be used.
      Source=mscorlib
      StackTrace:
           at System.StubHelpers.StubHelpers.StubRegisterRCW(Object pThis, IntPtr pThread)
           at System.Management.IWbemServices.CancelAsyncCall_(IWbemObjectSink pSink)
           at System.Management.SinkForEventQuery.Cancel()
           at System.Management.ManagementEventWatcher.Stop()
           at System.Management.ManagementEventWatcher.Finalize()
      InnerException: 
    
    1 回复  |  直到 11 年前
        1
  •  0
  •   Tallmaris    14 年前

    就在今天,我遇到了同样的问题,基本上我无法对类调用dispose,并且没有释放wmi对象,这给了我同样的错误。

    最后,我实现了一个不同的接口,而不是idisposable,公开了两个方法:in it和teardown,并使用这些方法设置我的mew并处理它。不过,这有点麻烦,如果类的用户不知道这一点,他将永远不会调用这两个方法,并且您的新程序将永远不会启动或被释放。

    另一种方法可能是让类连接到类似“ondestroy”的事件,并相应地通过删除mew对象来响应。

        public void Init()
        {
            if (mew == null)
            {
                mew = new ManagementEventWatcher(query);
                mew.EventArrived += mew_EventArrived;
                mew.Start();
            }
        }
    
        public void TearDown()
        {
            if (mew != null)
            {
                mew.Stop();
                mew.Dispose();
                mew = null;
            }
        }
    

    编辑:是的,我意识到这不是你想要的答案,我不认为有任何方法可以避免这一点,用户必须知道如何使用这个类…: