GC.SuppressFinalize() はいつ使用すればよいですか? 質問する

GC.SuppressFinalize() はいつ使用すればよいですか? 質問する

.NET では、どのような状況で を使用すればよいですかGC.SuppressFinalize()?

この方法を使用するとどのような利点がありますか?

ベストアンサー1

SuppressFinalizeファイナライザを持つクラスによってのみ呼び出されます。thisオブジェクトが完全にクリーンアップされたことをガベージ コレクター (GC) に通知します。

IDisposableファイナライザーがある場合の推奨パターンは次のとおりです。

public class MyClass : IDisposable
{
    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                // called via myClass.Dispose(). 
                // OK to use any private object references
            }
            // Release unmanaged resources.
            // Set large fields to null.                
            disposed = true;
        }
    }

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

    ~MyClass() // the finalizer
    {
        Dispose(false);
    }
}

通常、CLR は、オブジェクトが作成されるときにファイナライザを使用してオブジェクトを監視します (これにより、オブジェクトの作成コストが高くなります)。GC にSuppressFinalize、オブジェクトが適切にクリーンアップされ、ファイナライザ キューに入れる必要がないことを伝えます。これは C++ デストラクタのように見えますが、そのように動作することはありません。

SuppressFinalizeオブジェクトはファイナライザ キューで長時間待機する可能性があるため、最適化は簡単ではありません。他のオブジェクトを呼び出したくても、そうしないでください。SuppressFinalize重大な欠陥が発生する可能性があります。

設計ガイドラインでは、オブジェクトが を実装する場合、ファイナライザーは不要であるとされていますIDisposableが、ファイナライザーがある場合は、IDisposableクラスの確定的なクリーンアップを可能にするために を実装する必要があります。

ほとんどの場合、リソースをクリーンアップするだけで済むはずIDisposableです。ファイナライザーが必要になるのは、オブジェクトがアンマネージ リソースを保持しており、それらのリソースがクリーンアップされることを保証する必要がある場合のみです。

IDisposable注:コードがオブジェクトを適切に破棄したかどうかをテストするために、コーダーが独自のクラスのビルドをデバッグするためのファイナライザーを追加することがありますIDisposable

public void Dispose() // Implement IDisposable
{
    Dispose(true);
#if DEBUG
    GC.SuppressFinalize(this);
#endif
}

#if DEBUG
~MyClass() // the finalizer
{
    Dispose(false);
}
#endif

おすすめ記事