.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