Speicherverlust in der WPF-App aufgrund von DelegateCommand

8

Ich habe gerade Desktop-Apps fertig gestellt, die in WPF und c # mit MVVM-Pattern geschrieben wurden. In dieser App habe ich die Delegate Command-Implementierung verwendet, um die ICommands-Eigenschaften zu umbrechen, die in meinem ModelView verfügbar sind. Das Problem ist, dass diese DelegateCommands verhindern, dass ModelView und View nach dem Schließen der Ansicht als Garbage Collected erfasst werden. Es bleibt also solange larking, bis ich die gesamte Anwendung beendet habe. Ich profiliere die Anwendung Ich finde, dass es alles über delegatecommand ist, der das modelview in Gedächtnis behält. Wie könnte ich diese Situation vermeiden und ist dies in der Natur der MVVM-Muster, oder es ist über meine Implantation des Musters ?. Danke.

Edit: Dies ist ein kleiner, aber vollständiger Teil davon, wie ich das MVVM-Muster implementiere

Erstens: CommandDelegte-Klasse

%Vor%

Zweitens: ModelView-Klasse

%Vor%

Drittens: Fenstercode hinter

%Vor%

Weiter: Mein XAML

%Vor%

    
Abdullah BaMusa 15.06.2010, 10:48
quelle

3 Antworten

8

Was enthält in Ihrem Fall einen Verweis auf was?

  1. DelegateCommand enthält einen Verweis auf ViewModel - seine Eigenschaften execute und canExecute enthalten Verweise auf Methoden der ViewModel -Instanz.

  2. ViewModel enthält einen Verweis auf DelegateCommand - seine Eigenschaft PrintCommand .

  3. Die Ansicht enthält eine beliebige Anzahl von Verweisen auf ViewModel .

  4. Der CommandManager enthält einen Verweis auf DelegateCommand in seinem RequerySuggested -Ereignis.

Diese letzte Referenz ist ein Sonderfall: CommandManager verwendet WeakReference in seinem RequerySuggested -Ereignis, so dass trotz der Tatsache, dass DelegateCommand sich für dieses Ereignis registriert, es immer noch Müll-gesammelt werden kann.

Angesichts all dieser Dinge sollten Sie kein Problem haben. Wenn die Ansicht entsorgt wird, sollte weder ViewModel noch DelegateCommand erreichbar sein.

Sie sagen, Sie haben die Anwendung profiliert, und DelegateCommand enthält einen Verweis auf ViewModel . Es scheint mir, dass die logische nächste Frage sein sollte: Was enthält einen Verweis auf DelegateCommand ? Es sollte nicht CommandManager sein. Haben Sie etwas anderes in Ihrer Anwendung, das auf Ihre Befehle verweist?

    
Robert Rossney 15.06.2010 17:53
quelle
1

Ich denke, dass es in diesem Code eine zirkuläre Referenz gibt, die dazu führt, dass das ViewModel niemals als Garbage Collected erfasst wird.

Ich weiß, das ist eine alte Frage, aber ich werde darauf hinweisen, dass einige Implementierungen von DelegateCommand oder RelayCommand enthält eine WeakReference für die Aktion. Die Verwendung des DelegateCommand ist hier typisch, führt aber bei dieser Implementierung leider zu Speicherverlusten, da, wenn die ViewModel-Methode in den Konstruktor des DelegateCommand übergeben wird, automatisch ein Verweis auf die Klasse, die diese Methode enthält, vom Delegaten erfasst wird.

Wenn Sie IDispose in Ihrem ViewModel implementiert und die Verweise auf die DelegateCommands explizit in Dispose gelöscht haben, können Sie diese Implementierung weiterhin verwenden. Ihre Ansicht, die Ihr ViewModel erstellt, müsste jedoch auch Dipose daraus machen.

    
Malaise 17.03.2014 07:53
quelle
1

Nachdem ich diesen Beitrag gelesen hatte, stieß ich auf eine Webseite mit einigen Informationen. Es ist eine Seite auf CodePlex namens Speicherverlust von DelegateCommand.CanExecuteChanged Ereignisse verursacht.

Berichtet von: huetter
Aktualisiert von: dschenkelman

  

Beim Profiling meiner Anwendung habe ich festgestellt, dass es viele EventHandler gibt   war nie von DelegateCommands abgemeldet worden   CanExecuteChanged-Ereignis. Also diese EventHandler waren noch nie   Garbage-Collector, die einen schwerwiegenden Speicherverlust verursacht.

     

Die Registrierung von CanExecuteChanged-EventHandles erfolgt außerhalb   Anwendungsbereich Code Ich hatte erwartet, dass sie abgemeldet werden   automatisch auch. An diesem Punkt dachte ich, das könnte genauso gut sein   ein ThirdParty WPF-Kontrollproblem, aber weiter graben lese ich einen Blog   Post besagt, dass „WPF das ICommand.CanExecuteChanged-Ereignis erwartet   WeakReferences für EventHandler anzuwenden. "Ich habe es mir angesehen   RoutedCommand und bemerkte es WeakReferences auch verwendet wird.

     

Ich habe DelegateCommand angepasst, um eine ähnliche Implementierung zu verwenden   Das CanExecuteChanged-Event von RoutedCommand und der Speicherleck waren   Weg. Das gleiche gilt für CompositeCommand.

     

Geschlossen am 3. November 2009 um 18:28 Uhr von Dieses Problem wurde in der behoben   Prism-v2.1 release, so dass das Workitem jetzt geschlossen ist. Prism 2.1 kann sein   heruntergeladen von hier:
Ссылка

    
Sheridan 07.04.2013 15:57
quelle

Tags und Links