5

(1)IDisposableに関する多くの質問を読みましたが、処理時間がかかるために本当に必要な場合を除いて、Finalizeを使用しないことをお勧めします。
私が見たことがないのは、この費用がいくらで、どれくらいの頻度で支払われるかです。ミリ秒ごと?2番目?時間、日など

(2)また、オブジェクトを破棄できるかどうかが常にわからない場合は、Finalizeが便利だと思います。たとえば、フレームワークのフォントクラスです。フォントが共有されているかどうかがわからないため、コントロールはそれを破棄できません。フォントは通常、デザイン時に作成されるため、ユーザーはそれを破棄する必要がありません。したがって、参照が残っていない場合は、ファイナライズキックインで最終的にフォントを削除します。それは正しい印象ですか?

4

5 に答える 5

8

ファイナライズの主な問題は、オブジェクトがガベージコレクションされないようにブロックすることです。代わりに、ファイナライザーが呼び出され、オブジェクトは「次の実行時に」収集されます。技術的には、IIRCファイナライザーは別のスレッドでオブジェクトのリストを実行します。とにかく、これは「msごと」の問題ではなく、「オブジェクトを取り除くために複数のGCを実行する必要があります。

于 2010-06-15T13:57:28.783 に答える
4

FinalizeはDisposeとは概念的に異なります。Finalizeは、管理されていないリソースのみを解放できます。Disposeは、管理対象リソースと管理対象外リソースを解放できます。必要に応じてそれぞれを使用する必要があります。(ファイナライザーを持つクラスは常にIDisposableを実装する必要があることに注意してください)。

Disposeは明示的に呼び出す必要があります。Finalizeは、GCからのみ呼び出すことができます。

更新: IDisposableとファイナライザーを実装する方法に関する私のブログ投稿を参照してください:3つの簡単なルール。

于 2010-06-15T14:00:32.357 に答える
1

2番目の質問にお答えします。

いいえ、Finalizeこのように使用しないでください。実際、ごくわずかなフリンジケースを除いて、クラスがアンマネージリソースを直接Finalize保持している場合にのみ、オーバーライド(またはC#でデストラクタを宣言)する必要があります。

あなたが説明した問題は所有権の1つです。クラスの所有者は、IDisposableその存続期間といつ電話をかけるかを決定する責任がありますDispose。コードの他の部分はそのクラスを自由に使用できますが、所有権を主張できないため、そのクラスのライフタイム管理に参加しないでください。

残念ながら、私はFontクラスについてあまりよく知らず、あなたの質問のきっかけとなった特定のシナリオとどのように関連するかもしれませんが、あなたに当てはまるかもしれない一般的な声明を出すことができます。コードが(コンストラクターを介して)インスタンスを直接作成しなかった場合、コードは所有者と見なされるべきではありません。その場合、処分の責任は他の人に委ねられます。

于 2010-06-15T16:24:41.537 に答える
1

IDisposableとFinalizingについてのブログ投稿がありますが、パフォーマンスについてではありません。

于 2010-06-15T14:06:38.603 に答える
0

Finalizeは、ダブルチェックとして非常に役立ちます。クラッシュまたは誰かの悪いコードがスコープ外になる前にオブジェクトを破棄しない場合は、そのリソースがファイナライザーで解放されることを保証します。

ディスポーザでいくつかの凝ったフットワークを行うことができますが、GC.SuppressFinalize(this)これを呼び出すことで、両方の状況で機能するメソッドを記述し、コードが適切に機能することを保証できます。

オブジェクトを破棄する必要があることを人々に思い出させるフレームワークを作成している場合は、MDAを起動することもできます。

ファイナライザーのペナルティは、基本的に、オブジェクトをレベル2キューにプッシュすることになり、実行に時間がかかることです。オブジェクトを一貫して使用していて、それらがファイナライズしている場合、ファイナライザスレッドを実行するためだけに必要以上にレベル2コレクションが実行される可能性があります。

于 2010-06-15T14:02:35.643 に答える