finalize compare を dispose に使用しない方が本当に良いですか? 最初の解析で管理されていないリソースを削除しますか?
finalize を抑制するとは何ですか?
IDisposableの実装は次のようになります。
public MyClass : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected Dispose(bool disposing)
{
if( disposing )
{
// release unmanaged resource
}
// release managed resources
}
~MyClass()
{
Dispose(false);
}
}
オブジェクトにファイナライザーがある場合、CLRはそのオブジェクトへの参照をファイナライズキューに保持します。オブジェクトを手動で破棄する場合(Dispose()を呼び出す)、アンマネージリソースはすでに削除されているため(disposeの実装とファイナライザーが共有されるため)、ファイナライザーを呼び出す必要はなく、オブジェクトをファイナライズから安全に削除できます。キュー(GC.SuppressFinalize(this)を呼び出す)。
IDisposable と Finalizers の実装方法: 3 つの簡単なルールというブログ投稿を書きました。この記事では、それぞれをいつ、どのように使用するかについてかなり詳しく説明しています。この件に関するいくつかの Q&A もあります。
IDisposable
実装方法(および対応する FxCop ルール)に関する悪名高い Microsoft のドキュメントは、恐ろしく古くなっています。IDisposable
それらは、Microsoftが .NET 1.0 でどのように実装したかを正確に説明しています。v2.0 が公開されたとき、BCL のほとんどすべてのクラスは、私のブログ投稿で説明したものと同様のガイドラインに従うように改造されました (唯一の違いは、MicrosoftがDispose(bool)
基本クラスとして使用するために設計されたクラスに対して保護されていることです)。特に、私の知る限り、マネージド リソースとアンマネージド リソースの両方を担当する BCL クラスはありません。
通常、DisposeとFinalizeの両方で、管理されていないリソース(ハンドルなど)がクリーンアップされます。GCがオブジェクトが使用されなくなったことを検出すると、次の2つのいずれかが発生します。最良の場合、オブジェクトをファイナライズする必要がない場合(アンマネージリソースがないか、suppress finalizeと呼ばれる人がいない場合)、オブジェクトはすぐにクリーンアップされます。最悪の場合、ファイナライズが必要なもののために別の領域に配置され、最終的にファイナライザーが実行されてオブジェクトが完全にクリーンアップされるまで、より長く存続します(管理されていないリソースに長く留まります)。
ファイナライズが必要なオブジェクトが多数あると、パフォーマンスに大きな影響を与える可能性があります。廃棄には2つの目的があります。管理されていないリソースを返すことと、GCにブレークを与えるファイナライザー(Disposeを正しく実装していると仮定)を抑制することです。それでも、Disposeを呼び出す(またはUsingを使用する)ことを忘れる可能性があるため、ファイナライザーが存在する必要があります。それに頼らないようにしてください。