In Visual Basic ermöglicht die Implementierung des IDisposable-Interfaces (Dispose-Muster) eine korrekte Freigabe von Ressourcen (z.B. Dateien, Datenbankverbindungen, grafische Objekte), die nicht vom Garbage Collector verwaltet werden.
Eine typische Implementierung sieht wie folgt aus:
Public Class FileManager Implements IDisposable Private fileStream As FileStream Private disposed As Boolean = False Public Sub New(path As String) fileStream = New FileStream(path, FileMode.Open) End Sub Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub Protected Overridable Sub Dispose(disposing As Boolean) If Not disposed Then If disposing AndAlso fileStream IsNot Nothing Then fileStream.Dispose() End If disposed = True End If End Sub Protected Overrides Sub Finalize() Dispose(False) MyBase.Finalize() End Sub End Class
Wichtig: Verwenden Sie die Konstruktion Using ... End Using — sie stellt sicher, dass Dispose automatisch aufgerufen wird:
Using manager As New FileManager("data.txt") ' Dateioperationen End Using
Feinheiten:
Frage: "Warum ist der Aufruf von GC.SuppressFinalize(Me) innerhalb der Dispose-Methode erforderlich?"
Richtige Antwort: Es teilt dem Garbage Collector mit, dass der Finalizer nicht aufgerufen werden muss, da die Ressourcen bereits manuell über Dispose bereinigt wurden. Ohne dies wird der Finalizer unnötig ein weiteres Mal ausgeführt, was die Leistung beeinträchtigen und zu doppelter Bereinigung führen kann.
Geschichte
In einer Banksoftware wurde IDisposable inkorrekt implementiert — der Dispose-Aufruf für die Datenbank wurde vergessen, was zu Verbindungslecks führte. Im Durchschnitt "hängt" die Anwendung nach 2–3 Tagen ununterbrochener Arbeit.
Geschichte
In einem medizinischen Dienst wurde Dispose falsch implementiert (das Flag "disposed" fehlte). Die Dispose-Methode wurde mehrfach nacheinander aufgerufen, was zu Versuchen führte, dieselbe Ressource erneut freizugeben, und zu Ausnahmen führte.
Geschichte
In einem Grafikeditor wurde vergessen, GC.SuppressFinalize(Me) aufzurufen. Der Finalizer wurde sogar nach Dispose ausgeführt, was zu doppeltem Freigeben von Ressourcen und Instabilität (Zugriffsverletzung) führte.