2

COM オブジェクトに .NET ラッパーを使用するクラスがありますが、悪名高い RCW エラーが発生しているため、調査の結果、このクラスのファイナライザーから Dispose() メソッドを取り出すと修正されることがわかりました。たとえば、オブジェクトは破棄されていますが、登録されたイベントはまだぶらぶらしています...しかし、Dispose()を削除するだけでは答えになりません。なぜなら、誰がメモリを解放するのでしょうか? (私はメモリ プロファイラを実行し、Dispose メソッドを削除するだけで 20MB の余分な非管理メモリが発生することを確認しました)

だから私がDisposeモデルを使用している方法に何か問題があるはずです..ここに私が持っているものがあります:

  private MyCOMobject theCOMobject = null;

    static SuppressFieldCntrlr()
    {
        new SomeCalss();
    }

    ~SuppressFieldCntrlr()
    {
       Dispose(false); 
    }



    private bool disposed = false;

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                theCOMobject.Dispose();
            }

            MethodFoo(false);

            disposed = true;
        }
    }
4

2 に答える 2

3

COM オブジェクトの場合は、Marshal.ReleaseComObject. Marshal クラスは名前空間にありますSystem.Runtime.InteropServices

詳細はこちら

于 2012-11-28T16:00:00.573 に答える
2

管理されていないリソースは、パーツの外部に配置する必要がありますif(disposing)。そこでは、管理されたリソースのみを廃棄する必要があります。

COMラッパーの場合:

private void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                //Dispose managed resource if any.                   
            }

            //Release the unmanaged resource.

            disposed = true;
        }
    }

COMラッパーはIDisposableを実装しているため、Disposeパターンの実装はそのままにしておきます。

よくわかりませんReleaseComObject。どうやら必ずしもお勧めできるわけではありません。Marshal.FinalReleaseComObjectメソッドもあります。COMオブジェクトをラップする方法についてもこの回答をご覧ください。

ディスポーズパターンを実装する方法の詳細なガイドラインについては、JoeDuffyによるこのブログエントリを読むことができます。かなり長いですが、とても役に立ちます。

于 2012-11-28T16:09:41.053 に答える