この答え で見つかりました、
コードでDispose/Finalizeパターンが使用されている場合は、FinalizeメソッドのアンマネージリソースとDisposeメソッドのマネージリソースをクリーンアップします。
そして後で私は この素晴らしい記事 を見つけて、ファイナライズして破棄し、それらについて明確なアイデアを得ました。記事には、概念を説明する次のコード(ページ3)があります。
_class Test : IDisposable
{
private bool isDisposed = false;
~Test()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (disposing)
{
// Code to dispose the managed resources of the class
}
// Code to dispose the un-managed resources of the class
isDisposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
_
しかし、その下には同じメモ(この質問の冒頭に含めた)が表示されます。
Dispose/Finalizeパターンマイクロソフトでは、アンマネージリソースを使用する場合は、DisposeとFinalizeの両方を実装することをお勧めします。正しいシーケンスは、開発者がDisposeを呼び出すことになります。開発者がDisposeメソッドの明示的な呼び出しを怠った場合でも、Finalize実装が実行され、オブジェクトがガベージコレクションされたときにリソースが解放されます。 Francesco Balenaは彼のブログに「Dispose/Finalizeパターンは、アンマネージリソース(アンマネージメモリを含む)を割り当てるアンマネージコードを呼び出し、リソースを解放するために最終的に使用する必要があるハンドルを返す場合にのみ使用する必要があります。自分のメンバーを破棄またはファイナライズした後、親のそれぞれのメソッドを呼び出すことにより、親オブジェクトに連鎖します。」 Dispose/Finalizeパターンがコードで使用されている場合は、Finalizeメソッドでアンマネージリソースを、Disposeメソッドでマネージリソースを単純にクリーンアップします。
今、私は再び混乱しています。記事全体とコードサンプルでは、アンマネージリソースをDispose()
で解放する必要があることが示されています。しかし、そのコメントの関連性は何ですか?
編集:
この行が確認されたので:
コードでDispose/Finalizeパターンが使用されている場合は、Finalizeメソッドでアンマネージリソースを、Disposeメソッドでマネージリソースをクリーンアップします。
間違っています、私は編集しました この答え 。
その非常にシンプルな参照してください。
Dispose
とFinalize
。 Dispose
は、開発者がリソースを解放するために、不要になったとすぐに呼び出されます。 Dispose
を呼び出すのを忘れた場合、Frameworkは独自のGCサイクルでfinalizeを呼び出します(通常、独自の甘い時間がかかります)。Dispose()
を実装しますDispose()
で、まだ破棄していません。Finalize
もDispose
も実装しないでください。いくつかの古典的な例:
System.IO.FileStream
オブジェクトは、ファイルへのロック/ストリームハンドルを管理します。したがって、破棄とファイナライズの両方を実装します。開発者がそれを破棄した場合、他のプログラムはすぐにそれにアクセスできます。彼がそれを破棄するのを忘れた場合、フレームワークはそれをファイナライズし、GCサイクルの後半でハンドルを閉じます。
System.Text.StringBuilder
管理されていないリソースはありません。したがって、ファイナライズを破棄する必要はありません。
パターンに関する限り、それが何を意味するか
// Code to dispose the managed resources of the class
そのクラス内のコンポーネントとして持っている.NETオブジェクトのDisposeメソッドを呼び出すことです
そして
// Code to dispose the un-managed resources of the class
生のハンドルとポインタを閉じる手段。ここに例を含む更新されたコードがあります
class Test : IDisposable
{
private bool isDisposed = false;
~Test()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (!isDisposed)
{
if (disposing)
{
// Code to dispose the managed resources of the class
internalComponent1.Dispose();
internalComponent2.Dispose();
}
// Code to dispose the un-managed resources of the class
CloseHandle(handle);
handle = IntPtr.Zero;
isDisposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
これは古い質問です 説明する
Foo
に確定的クリーンアップの恩恵を受けるリソースがあるが、ファイナライザで有効にクリーンアップできるリソースがない場合、IDisposable
を実装する必要がありますが、Finalize
をオーバーライドしたり、デストラクタ。クラスが複数のリソースを保持し、ファイナライザで少なくとも1つをクリーンアップできる場合、ファイナライザでクリーンアップできる個別の各リソースを、独自のファイナライザ/デストラクタ搭載オブジェクト(保護されたネストされたクラス)、およびそれらのリソースを含むクラスは、ラッパーオブジェクトへの参照を保持する必要があります。これが完了すると、外部クラスは、Dispose
メソッドを使用するクラスのパターンに適合しますが、ファイナライザ/デストラクタはありません。