2

ManagementEventWatcherクラスを使用する.netライブラリを構築しました。私のライブラリは使い捨てなので、通常は using ステートメントでラップし、ManagementEventWatcherクラスはライブラリによって破棄されます。

私の問題は、ライブラリが COM に公開されており、使い捨てパターンを使用しない VB6 で使用されることです。ユーザーが .net アプリケーション内からライブラリで dispose を呼び出さない場合、または VB6 のためにできない場合、クラスはfrom withinManagementEventWatcherをスローします。InvalidComObjectExceptionSinkForEventQuery.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: 
4

1 に答える 1

0

今日も同じ問題がありました。基本的に、クラスで dispose を呼び出すことができず、WMI オブジェクトが破棄されていなかったため、同じエラーが発生しました。

最終的に、IDisposable ではなく別のインターフェイスを実装して、Init と TearDown の 2 つのメソッドを公開し、これらのメソッドを使用して MEW をセットアップして破棄しました。ただし、クラスのユーザーがこれを知らない場合、2 つのメソッドを呼び出すことはなく、MEW は起動または破棄されません。

もう 1 つの方法は、クラスを "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;
        }
    }

編集:はい、これはあなたが探していた答えではないことを認識しています。とにかくこれを回避する方法はないと思います。ユーザーはクラスの使用方法を知っている必要があります... :/

于 2011-03-23T13:46:00.037 に答える