Class ComponentsContainer ' a component contains other components'
Inherits System.ComponentModel.Component
Private foo as New Component
Private bar as New Component
Protected Override Sub Finalize()
foo.Dispose() ' HERE ? '
bar.Dispose()
MyBase.Finalize()
End Sub
Protected Overrides Sub Dispose(disposing As Boolean)
If disposing Then
foo.Dispose() ' OR HERE ? '
bar.Dispose()
End If
MyBase.Dispose(disposing)
End Sub
End Class
4 に答える
ファイナライザーからマネージド リソースを破棄しないでください (する必要はありません)。
Protected Override Sub Finalize()
' foo.Dispose() '
' bar.Dispose() '
MyBase.Finalize()
End Sub
このことから、クラスにアンマネージリソースがない場合、Finalizer はまったく必要ないということになります。
注: クラスにオーバーロードがありませPublic Sub Dispose()
ん。
編集:
foo
とは管理対象リソース (コンポーネントを拡張) であるためbar
、必要なのはProtected Overrides Sub Dispose(disposing As Boolean)
メソッドのみです。質問のバージョンは正しいです。をドロップするだけFinalize()
です。
ファイナライザーは、このクラスが所有するオブジェクトを直接破棄するのではなく、破棄パラメーターに false を渡して、このクラスの Dispose を呼び出す必要があります。MSDNを参照してください。
編集:質問に答えるには、所有しているオブジェクトの破棄は、Finalize ではなく Dispose で行う必要があります。
編集 2:これは、オブジェクトが破棄されずにファイナライズされた場合、Dispose は "false" パラメーターでのみ (Finalize によって) 呼び出され、子オブジェクトはこのクラスによって破棄されないことを意味します。これらはマネージド オブジェクトであり、明示的に破棄されていない場合、フレームワークがそのように感じたときにファイナライズされるため、これは正しいことです。
Dispose
ガベージ コレクタがオブジェクトを解放する前に、明示的に一部のリソースを解放したい場合です。
Finalize
ガベージ コレクタがオブジェクトを解放する際に自動的に呼び出されます。
リソースを保持するオブジェクトが多数ある場合は、ガベージ コレクションを制御するべきではないため、Dispose を使用する必要があります。
フレームワークのドキュメントから:
Dispose によって明示的な制御を提供する場合でも、Finalize メソッドを使用して暗黙的なクリーンアップを提供する必要があることに注意してください。Finalize は、プログラマーが Dispose の呼び出しに失敗した場合に、リソースが永続的にリークするのを防ぐためのバックアップを提供します。
あなたは何から継承していますか?直接的または間接的 にSystem.ComponentModel.Containerであると思われます。
その場合、何もする必要はありません。System.ComponentModel.Containerは、含まれているすべてのコンポーネントをそのメソッドで自動的に破棄します。Dispose
放っておけば、破棄/終了パターンを実装する最も簡単な方法である必要があります。