2
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

4 に答える 4

3

ファイナライザーからマネージド リソースを破棄しないでください (する必要はありません)。

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()です。

于 2010-02-15T11:40:07.963 に答える
3

ファイナライザーは、このクラスが所有するオブジェクトを直接破棄するのではなく、破棄パラメーターに false を渡して、このクラスの Dispose を呼び出す必要があります。MSDNを参照してください。

編集:質問に答えるには、所有しているオブジェクトの破棄は、Finalize ではなく Dispose で行う必要があります。

編集 2:これは、オブジェクトが破棄されずにファイナライズされた場合、Dispose は "false" パラメーターでのみ (Finalize によって) 呼び出され、子オブジェクトはこのクラスによって破棄されないことを意味します。これらはマネージド オブジェクトであり、明示的に破棄されていない場合、フレームワークがそのように感じたときにファイナライズされるため、これは正しいことです。

于 2010-02-15T11:42:27.407 に答える
1

Disposeガベージ コレクタがオブジェクトを解放する前に、明示的に一部のリソースを解放したい場合です。

Finalizeガベージ コレクタがオブジェクトを解放する際に自動的に呼び出されます。

リソースを保持するオブジェクトが多数ある場合は、ガベージ コレクションを制御するべきではないため、Dispose を使用する必要があります。

フレームワークのドキュメントから:

Dispose によって明示的な制御を提供する場合でも、Finalize メソッドを使用して暗黙的なクリーンアップを提供する必要があることに注意してください。Finalize は、プログラマーが Dispose の呼び出しに失敗した場合に、リソースが永続的にリークするのを防ぐためのバックアップを提供します。

アンマネージ リソースをクリーンアップするための Finalize と Dispose の実装

于 2010-02-15T11:45:50.130 に答える
1

あなたは何から継承していますか?直接的または間接的 にSystem.ComponentModel.Containerであると思われます。

その場合、何もする必要はありません。System.ComponentModel.Containerは、含まれているすべてのコンポーネントをそのメソッドで自動的に破棄します。Dispose放っておけば、破棄/終了パターンを実装する最も簡単な方法である必要があります。

于 2010-02-15T12:13:37.610 に答える