Es gibt eine komplexe App, ich versuche, das Szenario zu vereinfachen. Es gibt einen Host .exe (.NET), der viele Steuerelemente (ActiveX, .NET, WPF) enthält.
Ein Steuerelement ist im Grunde ein Raster mit Elementen (nennen Sie es "Liste"), und wenn neue Auswahl passiert, sendet es eine Nachricht an ein anderes WPF-Steuerelement (nennen Sie es "DataView"). "DataView" zeigt Details der aktuellen Auswahl von "Liste" an.
Wenn DataView diese Nachricht empfängt, erstellt es das ViewModel neu und weist es seinem DataContext zu, sodass die Ansicht erneut erstellt wird. Seine Ansicht ist sehr komplex (XAML deklariert), voller Steuerelemente, Vorlagen und enthält auch mehrere Bilder (Typ: NonDPIImage, abgeleitet von Image, mit ein paar grundlegende nicht wichtige Änderung, nur als Bild), und es ist Quelle ist ein Konverter, der die BitmapImages erstellt.WPF View-Leck - unsichtbar, aber immer noch im Hintergrund gerendert
Es funktioniert gut, aber ich habe festgestellt, dass nach der Änderung der Auswahl das "DataView" Update immer langsamer wird.
Ich debuggte, und festgestellt, dass nach mehreren Auswahländerungen alle vorherigen Ansichten noch im Speicher sind, und alle rendering seinen Inhalt, so dass der ImageConverter für alle vorherigen Ansichten aufgerufen wird, damit es immer langsamer wird.
Ich habe versucht, Profil, das ist, was ich nach 10+ Auswahl sehe.
Sie sehen die bisherigen Ansichten noch in dem Speicher (niedriges Prio Problem) sind, mit den Bildern, und diese werden noch gemacht werden (hohe Prio Problem), so dass die App langsamer und langsamer.
Ich bin nicht wirklich vertraut mit WPF, ich lese nach Lecks (meist nicht DependencyProperty verwendet oder ähnlich), aber dieses Steuerelement ist so schwer, dass ich zunächst schnell umgehen, so verhindern, dass die durchgesickerten Ansichten, und später Untersuchen Sie das Speicherproblem. (natürlich wären beide die besten ...)
habe ich versucht vor DataContext einem neuen Wert zugewiesen, setze die aktuelle View Image.Quelle auf null, damit zumindest das durchgesickerte Image sich nicht rendern lässt, sondern Das hat dazu geführt, dass die neue View (!) auch ihre Image.Source verliert, so wie WPF Caching oder Sharing wie statische Daten?
Da mein erstes Prio ist, das "unsichtbare Rendern" zu stoppen, habe ich danach versucht, einige der Modelleigenschaften auf Null zu setzen, bevor ich das neue erstellte (damit es immer noch leckt, aber zumindest kein Rendern mehr), Wenn Converter also Eigenschaften erhält, um das Image zu erstellen, wird es als null angezeigt und das Rendern übersprungen.
Aber es verhält sich sehr seltsam!
Für die durchgelaufenen Instanzen wird der Haltepunkt im properties_get-Code nicht getroffen, so wie WPF die Werte zwischenspeichert? Das hat mich daran gehindert, diesen Weg fortzusetzen.
Jede Hilfe/Idee würde Jungs geschätzt werden.
Ja, es erstellt das Bild aus Code, aber es ruft die 'bitmapImage-> Freeze();' - wie in Ihrem Link vorgeschlagen, um ein Leck zu verhindern. – Zotyi
Befindet sich ein Event-Handler auf dem Image-Objekt? Entweder aus Code oder aus der Sicht (XAML)? irgendein Verhalten? – Mishka
Ich glaube, ich habe das Problem gefunden: Es wurde ein Nachrichten-Hook zur View HwndSource hinzugefügt (AddHook()), aber wurde nicht entfernt (zum Beispiel in UserControl_Unloaded). Dies behielt die gesamte Ansicht (siehe die rote Rechtecke-Klasse). – Zotyi