7 Stimmen

VB.NET - Sollte eine Finalize-Methode hinzugefügt werden, wenn IDisposable implementiert wird?

In Visual Studio, wenn ich die Zeile " Implements IDisposable ", fügt die IDE automatisch hinzu:

  • a disposedValue Mitgliedsvariable
  • a Sub Dispose() Implements IDisposable.Dispose
  • a Sub Dispose(ByVal disposing As Boolean)

El Dispose() sollte in Ruhe gelassen werden, und der Bereinigungscode sollte in Dispose(disposing) .

Doch die Entsorgen Finalisieren Muster sagt, dass man auch die Sub Finalize() anrufen Dispose(False) . Warum fügt die IDE dies nicht auch hinzu? Muss ich es selbst hinzufügen, oder wird es irgendwie implizit aufgerufen?

EDITAR: Irgendeine Idee, warum die IDE automatisch 80% der erforderlichen Dinge hinzufügt, aber die Finalize-Methode auslässt? Ist der Sinn dieser Art von Funktion nicht, Ihnen zu helfen no diese Dinge vergessen?

EDIT2: Ich danke Ihnen allen für Ihre ausgezeichneten Antworten, jetzt ergibt das alles einen Sinn!

11voto

Jonathan Rupp Punkte 15162

Wenn Sie tatsächlich nicht verwaltete Ressourcen halten, die nicht automatisch durch den Garbage Collector aufgeräumt werden, und diese in Ihrer Dispose() aufräumen, dann ja, sollten Sie das gleiche in Finalize() tun.

Wenn Sie IDisposable aus einem anderen Grund implementieren, ist die Implementierung von Finalize() nicht erforderlich.

Die grundlegende Frage ist folgende: Wenn Dispose() nicht aufgerufen wird und Ihr Objekt in den Müll wandert, würde dann Speicher verloren gehen? Wenn ja, implementieren Sie Finalize. Wenn nein, brauchen Sie das nicht. Vermeiden Sie es auch, Finalize zu implementieren, "nur weil es sicherer ist". Objekte mit benutzerdefinierten Finalizern können potentiell zwei GC-Durchläufe benötigen, um sie freizugeben -- einmal, um sie in die Warteschlange der ausstehenden Finalizer zu stellen, und einen zweiten Durchlauf, um ihren Speicher tatsächlich freizugeben.

3voto

Matt Howells Punkte 38730

Nein, Sie brauchen Finalize nicht, es sei denn, Sie haben nicht verwaltete Ressourcen zu bereinigen.

In den meisten Fällen ist der Grund, warum eine Klasse disposable ist, der, dass sie Referenzen auf andere verwaltete IDisposable-Objekte enthält. In diesem Fall ist keine Finalize-Methode notwendig oder wünschenswert.

2voto

missa Punkte 31
Implements IDisposable

Public Overloads Sub Dispose() Implements IDisposable.Dispose

    Dispose(True)
    GC.SuppressFinalize(Me)

End Sub

Protected Overloads Sub Dispose(ByVal disposing As Boolean)

    If disposing Then
        ' Free other state (managed objects).
    End If
    ' Free your own state (unmanaged objects).
    ' Set large fields to null.
End Sub

Protected Overrides Sub Finalize()

    Dispose(False)
    MyBase.Finalize()

End Sub

1voto

Greg Beech Punkte 127525

Wie andere bereits gesagt haben, brauchen Sie keinen Finalizer zu implementieren, es sei denn, Sie halten direkt nicht verwaltete Ressourcen. Außerdem, vorausgesetzt, Sie arbeiten in .NET 2.0 oder höher, ist es unwahrscheinlich, dass Sie jemals einen Finalizer implementieren müssen, weil in der Regel SafeHandle verwendet werden kann, um Ihre nicht verwalteten Ressourcen zu umhüllen.

Ich schrieb eine ziemlich langer Blogbeitrag über den Hintergrund und die Implementierung von IDisposable und Finalizern vor einiger Zeit, die es wert sind, gelesen zu werden, wenn Sie sich nicht ganz im Klaren darüber sind.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X