0

私のクラスは COM リソースを使用しており、IDisposable から継承しています。アンマネージ リソースをクリーニングするために、Marshall.ReleaseCOMObject() メソッドを呼び出している Dispose() メソッドがあります。COM リソースを解放するには?finalzier メソッドがあり、その中で Marshal または Dispose を呼び出すと、RCW エラーが発生し、ファイナライザー メソッドを削除すると、RCW エラーは発生しなくなります。しかし、メモリ プロファイラーを見ると、アンマネージ リソースが表示されます。このCOMリソースを含むフォームを開くたびにメモリが増え続けます...だから、それがクリーンアップされていないように見えますか? では、C# アプリで COM リソースをクリーンアップする正しい方法は何でしょうか?

すぐにいくつかのコードサンプルで質問を更新します。

ありがとう。

private MyCOMobject theCOMobject = null;

static SuppressFieldCntrlr()
{
    new SomeCalss();
}


private bool disposed = false;

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

private void Dispose(bool disposing)
{
    if (!this.disposed)
    {
        if (disposing)
        {
           //nothing in here, is it just for Managed Resources? 
        }

        Marshal.ReleaseComObject(this);
        MethodFoo(false);

        disposed = true;
    }
}
4

3 に答える 3

2

クラスがアンマネージリソースを直接所有しておらず、派生クラスがアンマネージリソースを直接所有しないことがわかっている場合(たとえば、クラスが封印されているため、クラスが内部であるため)、ファイナライザーは必要ありません。

個人的には、厳密に必要ではない場合でも、ファイナライザーを使用して標準パターンを実装します。主に驚き最小の原則のためであり、他の誰かがそれを開封するか、将来的に管理されていないリソースを持つ派生クラスを許可することを決定する可能性があるためです。

COMオブジェクトは管理対象リソースであるため、破棄がtrueの場合はReleaseComObjectを呼び出す必要があることにも注意してください。

private void Dispose(bool disposing)
{
    if (!this.disposed)
    {
        if (disposing)
        {
            // Dispose managed resources
            Marshal.ReleaseComObject(this);
        }
        // If you directly own unmanaged resources, they'd be freed here

        disposed = true;
    }
}
于 2012-11-28T17:26:47.657 に答える
2

管理されていないオブジェクトではなく、管理されたオブジェクトをカプセル化しています。Win32ファイルハンドルやデバイスコンテキストなどを取得するためにP/invokeを実行していません。むしろ、管理対象オブジェクト(RCW)への参照を取得しました。Marshal.ReleaseComObjectメソッドのif (disposing)セクションにを呼び出す必要がありますDispose(bool)

RCW自体にはIUnknown->Release()、実際のCOMオブジェクトのブックキーピングを処理するファイナライザーがあります。したがって、ファイナライズが必要なポイントでまだ呼び出していない場合ReleaseComObject、COMオブジェクトはガベージコレクターによって削除されます。

于 2012-11-28T17:27:59.823 に答える
0

管理されていないリソースがある場合は、ファイナライザーを強くお勧めします。この場合:

~ClassName
{
    Dispose(false);
}
于 2012-11-28T17:19:05.267 に答える