1. ホーム
  2. c#

[解決済み] GC.SuppressFinalize()はいつ使うべきですか?

2022-02-08 07:42:32

質問

.NETでは、どのような状況で GC.SuppressFinalize() ?

この方法を使うと、どんな利点がありますか?

どのように解決するのですか?

SuppressFinalize は、ファイナライザを持つクラスからのみ呼び出される必要があります。これは、ガベージコレクタ(GC)に this オブジェクトは完全にクリーンアップされました。

推奨される 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はファイナライザーを持つオブジェクトを作成する際に、そのオブジェクトを監視しています(作成コストが高くなる)。 SuppressFinalize は、オブジェクトが適切にクリーンアップされ、ファイナライザ・キューに入る必要がないことをGCに伝えます。これは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