Frage

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

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

Das Dispose() sollte in Ruhe gelassen werden, und der Aufräumcode sollte eingefügt werden Dispose(disposing).

Jedoch das Abschluss des Musters entsorgen sagt, du solltest auch außer Kraft setzen Sub Finalize() anrufen Dispose(False). Warum fügt die IDE das auch nicht hinzu? Muss ich es selbst hinzufügen oder wird es irgendwie implizit genannt?

BEARBEITEN: Irgendeine Idee, warum die IDE automatisch 80% der erforderlichen Dinge hinzufügt, aber die Abschlussmethode auslässt? Ist nicht der springende Punkt dieser Art von Funktion, die Ihnen hilft nicht diese Dinge vergessen?

Edit2: Vielen Dank für Ihre hervorragenden Antworten. Das macht jetzt vollkommen sinnvoll!

War es hilfreich?

Lösung

Wenn Sie tatsächlich nicht verwaltete Ressourcen halten, die vom Müllsammler nicht automatisch aufgeräumt werden und diese in Ihrem Dispose () aufräumen, sollten Sie dasselbe in Finalize () tun.

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

Die grundlegende Frage lautet: Wenn Dispose () nicht angerufen und Ihr Objektmüll gesammelt wurde, würde das Speicher auslaufen? Wenn ja, implementieren Sie die Abschluss. Wenn nein, müssen Sie nicht. Vermeiden Sie auch die Implementierung der Abschluss "nur weil es sicherer ist". Objekte mit kundenspezifischen Finalizern können möglicherweise zwei GC -Pässe benötigen, um sie zu befreien - einmal, um sie in die anstehende Schlange des Finalizers zu setzen, und einen zweiten Pass, um ihren Speicher tatsächlich zu befreien.

Andere Tipps

Nein, Sie müssen nicht abgeschlossen sein, wenn Sie nicht verwaltete Ressourcen zum Aufräumen haben.

In den meisten Fällen ist der Grund, warum eine Klasse verfügbar ist, weil sie Verweise auf andere verwaltete identifizierbare Objekte hält. In diesem Fall ist keine Abschlussmethode erforderlich oder wünschenswert.

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

Wie andere gesagt haben, müssen Sie keinen Finalizer implementieren, es sei denn, Sie haben direkt nicht verwaltete Ressourcen. Unter der Annahme, dass Sie in .NET 2.0 oder höher arbeiten, ist es unwahrscheinlich, dass Sie jemals einen Finalizer implementieren müssen, da in der Regel SafeHandle verwendet werden kann, um Ihre nicht verwalteten Ressourcen zu wickeln.

Ich habe a geschrieben Ziemlich langer Blog -Beitrag Abdeckung des Hintergrunds und der Implementierung von idisposabilen und endgültigen Abschlüssen vor einiger Zeit, was eine Lektüre wert sein kann, wenn Sie nicht ganz klar sind.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top