ManagementEventWatcher - InvalidComObjectException, когда приложение существует - PullRequest
2 голосов
/ 19 августа 2010

Я создал библиотеку .net, которая использует класс ManagementEventWatcher.Моя библиотека одноразовая, поэтому обычно я заключаю ее в оператор using, и класс ManagementEventWatcher удаляется моей библиотекой.

Моя проблема в том, что моя библиотека открыта для COM и используется в VB6, который не использует одноразовый шаблон.Если пользователь не вызывает dispose для библиотеки из своего приложения .net или не может из-за VB6, класс ManagementEventWatcher выдаст InvalidComObjectException из SinkForEventQuery.Cancel

I can 'Это исключение не сохраняется, поэтому оно остается необработанным, что нехорошо.Есть ли какие-то обходные пути, которые я могу попробовать?

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 Ответ

0 голосов
/ 23 марта 2011

У меня была такая же проблема только сегодня, в основном я не мог вызвать 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;
        }
    }

РЕДАКТИРОВАТЬ: Да, я понимаю, что это не тот ответ, который вы искали, я не думаю, что тамв любом случае это способ избежать этого, пользователь должен знать, как использовать класс ...: /

...