Ordnungsgemäße Bereinigung von WPF-Benutzersteuerelementen
Ich bin relativ neu in WPF, und einige Dinge sind sehr Fremd für mich. Für einen, im Gegensatz zu Windows Forms -, WPF-Steuerelement-Hierarchie nicht unterstützt IDisposable. In Windows Forms, wenn ein Benutzer-Steuerelement verwalteten Ressourcen, es war sehr leicht zu reinigen, die Ressourcen, die durch das überschreiben der Dispose-Methode, die jedes Steuerelement implementiert.
In WPF, die Geschichte ist nicht so einfach. Ich habe gesucht für mehrere Stunden, und traf auf zwei grundlegende Themen:
Das erste Thema ist Microsoft deutlich, die besagt, dass WPF nicht implementiert IDisposable, da die WPF-Steuerelemente haben keine nicht verwaltete Ressourcen. Während das mag wahr sein, offensichtlich haben Sie völlig übersehen die Tatsache, dass Benutzer-Erweiterungen, um Ihre WPF-Klassenhierarchie kann in der Tat die Verwendung von verwalteten Ressourcen (direkt oder indirekt über ein Modell). Von nicht der IDisposable implementiert, Microsoft hat wirksam entfernt werden die einzige Garantie-Mechanismus, mit dem nicht verwalteten Ressourcen verwendet, die von einem benutzerdefinierten WPF-Steuerelement oder ein Fenster bereinigt werden können.
Zweiten, fand ich ein paar Hinweise zum Disponenten.ShutdownStarted. Ich habe versucht, verwenden Sie die ShutdownStarted Ereignis, aber es scheint nicht, um das Feuer für jedes Steuerelement. Ich habe eine Reihe von WPF-Benutzersteuerelement, die ich umgesetzt haben, einen handler für ShutdownStarted, und es wird nie genannt. Ich bin nicht sicher, wenn es funktioniert nur für Windows, oder vielleicht ist die WPF-App Klasse. Es ist jedoch nicht richtig Schießen, und ich bin undicht öffnen PerformanceCounter Objekte jedes mal, wenn die app schließt.
Gibt es eine bessere alternative zum bereinigen nicht verwalteter Ressourcen als der Dispatcher.ShutdownStarted Veranstaltung? Gibt es irgendein trick, um der IDisposable implementiert, so dass Dispose aufgerufen wird? Ich würde viel lieber vermeiden mit einem finalizer, wenn überhaupt möglich.
InformationsquelleAutor der Frage jrista | 2009-10-11
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich habe Angst, dass Dispatcher.ShutdownStarted scheint wirklich das einzige zu sein, Mechanismus von WPF bietet für die Entsorgung von Ressourcen in Benutzersteuerelemente. (Siehe auch die sehr ähnliche Frage ich fragte vor einer Weile).
Einem anderen Weg zu nähern, das problem ist, verschieben Sie alle Ihre Einweg-Ressourcen (wenn überhaupt möglich) aus dem code hinter und in separate Klassen (wie die ViewModel-bei der Verwendung des MVVM-pattern). Dann auf einer höheren Ebene könnten Sie mit Ihren Haupt-Fenster schließen und informieren Sie alle ViewModels über eine Messenger-Klasse.
Ich bin überrascht, dass Sie nicht bekommen, der Dispatcher.ShutdownStarted Veranstaltung. Sind Ihre Benutzersteuerelemente befestigt, um die top-level-Fenster an der Zeit?
InformationsquelleAutor der Antwort Mark Heath
Die IDisposable-Schnittstelle hat (fast) keine Bedeutung unter WPF, da der Mechanismus unterscheidet sich von Winforms. In WPF, müssen Sie daran denken, dass die visuelle und logische Struktur: das ist fundamental.
Also, jedes visuelle Objekt im Allgemeinen Leben als Kind eines anderen Objekts. Die Basis der WPF-Gebäude Mechanismus zu befestigen, das visuelle Objekt hierarchisch, dann trennen und zerstören, wenn Sie nicht nützlich sind.
Ich denke, Sie können überprüfen Sie die
OnVisualParentChanged
- Methode ausgesetzt, da dieUIElement
: diese Methode wird aufgerufen, wenn ein visual-Objekt angehängt ist, und wenn getrennt ist. Das könnte der richtige Ort sein, um die Entsorgung der nicht verwaltete Objekte (sockets, Dateien, etc).InformationsquelleAutor der Antwort venezia
Ich war auf der Suche nach dieser und auch nach Prüfung der verschiedenen Optionen, die ich implementiert die Lösung von venezia
Ich erkannte, dass, wenn Eltern anrufen
Children.Clear()
Methode und hatte bereits hinzugefügte Elemente, um Kinder, DependencyObject hatte einen Wert. Aber als Elternteil Hinzugefügt ein Element (Children.Add(CustomControl)
) und die Kinder leer war DependencyObject war null.InformationsquelleAutor der Antwort Jaime Marín
Während andere haben Sie wirklich nützliche Informationen zu diesem problem, es ist ein wenig Informationen, können Sie nicht erklären, dass eine Menge darüber, warum es keine IDisposable. Im Grunde, WPF (und Silverlight) macht starken Gebrauch von WeakReferences - dies ermöglicht Ihnen eine Referenz zu einem Objekt, das der GC kann immer noch sammeln.
InformationsquelleAutor der Antwort Pete OHanlon