Ich habe eine Anwendung erstellt, die das AvalonDock-Framework verwendet. Ein Schlüsselelement ist die Möglichkeit, Domänenmodell-Entitäten mit AvalonDock.DocumentContent
abgeleiteten Editoren zu bearbeiten. Ich habe ein Problem gefunden und festgestellt, dass meine Editoren keine Müllsammlung sind, nachdem sie geschlossen und aus der Sammlung DockingManager.Documents
entfernt wurden.
Nach einiger fruchtloser Suche habe ich eine kleine Testanwendung erstellt, die auf folgende Weise neu erstellt werden kann:
AvalonDockLeak
; Document
; Ändern Sie Document.xmal zu:
%Vor%Ändern Sie Document.xmal.cs zu:
%Vor%Der Destruktor, den ich hinzugefügt habe, um das Problem zu diagnostizieren, indem ich einen Breakpoint für die Methode opening {hinzufüge und sehe, ob er getroffen wird. Es schließt immer die Testanwendung, aber nicht früher.
Ändern Sie jetzt Window1.xaml zu:
%Vor%Ändern Sie Window1.xaml.cs zu:
%Vor% Diese einfache Anwendung enthält auch das Leck. Dies kann durch den Haltepunkt in der ~Document()
Öffnung beobachtet werden {wird nicht nach dem Schließen eines DocumentContent
getroffen.
Nun, was ich jetzt möchte, ist das ein bekanntes Problem und gibt es einen Weg, es zu verhindern? Wenn die Objekte nach langer Zeit nur Müll gesammelt werden, was kann ich tun, um dies zu beschleunigen? Der Aufruf von GC.Collect () hilft übrigens nicht.
Ich empfehle Ihnen und allen, die AvalonDock 1.3 verwenden, dringend, auf Version 2.0 zu aktualisieren. Die neueste Version ist MVVM-freundlich und leidet nicht unter diesem Problem (Dokumente und Verankerungen werden ordnungsgemäß mit Müll gesammelt). Weitere Informationen: avalondock.codeplex.com
Danke
Offensichtlich werden die Referenzen Ihres DocumentContent von einem Eventhandler irgendwo gespeichert. Sie sollten einen Speicher-Profiler wie CLR-Profiler von Microsoft verwenden, um die Ursache zu ermitteln.
Sie sollten darauf achten, dass Sie eine registrierte Veranstaltung immer abmelden. Andernfalls können Sie ein Speicherleck erhalten. Dazu können Sie den Operator - = verwenden.
Das DocumentContent
wird standardmäßig beim Schließen versteckt, was bedeutet, dass die Referenz am Leben erhalten wird.
Wenn Sie DocumentContent
schließen und anschließend entsorgen möchten, müssen Sie einige Eigenschaften in einem abgeleiteten DocumentConcent
angeben oder die AvalonDock
Quelle ändern.
Jetzt, wenn es geschlossen ist, wird es die Referenz entsorgen, anstatt daran zu hängen, da es nur versteckt wurde.
Ich hatte auch ein Problem in dieser Richtung. Das Schließen von Tabs würde Speicherlecks verursachen. Ich habe es mit einem Profiler überprüft, und es stellte sich heraus, dass der ActiveContent immer noch einen Verweis enthielt und den GarbageCollector daran hinderte.
Mein Code zum Schließen des Tabs:
%Vor%Das hat den Job gemacht, den Tab zu schließen, aber ich habe gelernt, dass ich
anrufen muss %Vor%vor dem Entfernen des Inhalts aus dem documentPane, wenn ich möchte, dass ActiveContent auf null gesetzt wird und der GC seine Aufgabe erledigt.
Hinweis: Ich verwende Version 1.2 von AvalonDock, dies könnte sich in neueren Versionen geändert haben.
Tags und Links wpf c# garbage-collection avalondock