ManagementEventWatcher - 应用程序存在时出现 InvalidComObjectException

发布于 2024-09-15 03:12:40 字数 1011 浏览 7 评论 0原文

我已经构建了一个使用 ManagementEventWatcher 类的 .net 库。我的库是一次性的,因此通常我会将其包装在 using 语句中,并且 ManagementEventWatcher 类将由我的库处置。

我的问题是我的库暴露给 COM,并在 VB6 中使用,而 VB6 不使用一次性模式。如果用户未从其 .net 应用程序内调用库上的 dispose,或者由于 VB6 的缘故而无法调用 dispose,则 ManagementEventWatcher 类将从 InvalidComObjectException 中抛出 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: 

I have build a .net library that uses the ManagementEventWatcher class. My library is disposable, so normally I would wrap it in a using statement and the ManagementEventWatcher class would get disposed by my library.

My issue is that my library is exposed to COM, and gets used in VB6 which doesn't use the disposable pattern. If a user does not call dispose on the library from within their .net application, or can't because of VB6, the ManagementEventWatcher class will throw an InvalidComObjectException from within SinkForEventQuery.Cancel

I can't capture the exception, so it remains unhandled, which is not good. Are there some workarounds I can try?

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: 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

多情癖 2024-09-22 03:12:40

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

我最终所做的是实现一个不同的接口而不是 IDisposable,公开两个方法:Init 和 TearDown,并使用这些方法来设置我的 MEW 并处置它。不过,这有点像黑客,如果该类的用户不知道这一点,他将永远不会调用这两个方法,并且您的 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;
        }
    }

编辑:是的,我意识到这不是您正在寻找的答案,我认为无论如何都没有办法避免这种情况,用户必须知道如何使用该类...:/

I had the same problem just today, basically I could not call dispose on the class and the WMI object was not being disposed, giving me the same error.

What I did in the end was implement a different interface rather than IDisposable, exposing two methods: Init and TearDown, and use those method to set up my MEW and dispose it. It is a bit of a hack though, if the user of the class does not know this he will never call the two methods and your MEW will never start or be disposed.

Another way could possibly be to have the class hook up to an event like "OnDestroy" and respond accordingly by tearing down the MEW object.

    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;
        }
    }

EDIT: Yes I realize this is not the answer you were looking for, I don't think there is a way to avoid this anyway, the user must know how to use the class... :/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文