2010-06-03 17 views
21

In der neuesten Version von MVVM-Licht (V3 SP1) beide "Entsorgen()" und "Dispose (bool)" Methoden in Ansichtsmodell Klasse markiert sindCleanup vs Dispose (bool) in MVVM-Licht

Verwenden Sie diese Methode nicht mehr, sie wird in einer zukünftigen Version entfernt. Verwenden ICleanup.Cleanup() statt

Dies bedeutet, dass IDisposable-Schnittstelle darf nicht in allen Ansichtsmodell Klassen implementiert werden, die von GalaSoft.MvvmLight.ViewModelBase abgeleitet sind (und Bereinigung müssen overrided werden)?

Wenn ja, kann die Verwendung nicht für View-Model-Instanzen verwendet werden ... Wahrscheinlich habe ich etwas nicht verstanden ... Bitte klären ... Was sind die Vorteile einer solchen Bereinigung?

Danke.

Antwort

27

Das Problem ist historisch. Zuerst dachte ich, es wäre eine gute Idee, alle VMs zu IDisposable zu machen. IDisposable hat jedoch eine andere Absicht: Sobald die VM disponiert ist, wird (per Konvention) erwartet, dass so bald wie möglich Müll gesammelt wird. Nachdem ich mit Freunden gesprochen habe, wurde mir klar, dass es ein Fehler war, alle VMs zu IDisposable zu zwingen. Deshalb habe ich IDisposable durch ICleanup ersetzt. Die Absicht von ICleanup ist es, eine Möglichkeit zur Verfügung zu stellen, VMs zu säubern (z. B. ihren Status zu persistentem Speicher zu leeren, Streams zu schließen usw.), aber nicht unbedingt so, dass sie so bald wie möglich Müll gesammelt werden.

Nichts hindert Sie daran, dass Ihre VMs IDisposable implementieren. Ich wollte diese Beschränkung in der ViewModelBase-Klasse nicht beibehalten, weshalb diese Schnittstelle in V4 entfernt wird.

Der Vorteil von ICleanup besteht darin, dass Sie alle Ihre VMs in einem Aufruf von ViewModelLocator.Cleanup() bereinigen können. Es ist ein Hinweis für VM-Entwickler, dass VMs darüber nachdenken sollten, eine Bereinigungsmethode für ihre VMs bereitzustellen.

Macht das Sinn? Cheers, Laurent

+0

Danke für einen Kommentar, es auf jeden Fall Sinn machen, wenn Sie bearbeitbar VM nach seiner clening haben müssen ... Aber ich sehe keinen Grund, es zu reinigen, ohne zu entsorgen. .. Normalerweise entsorge ich VM bei der Schließung ... Warum muss ich es aufräumen, ohne zu schließen? Ich werde mit jeder Rückmeldung geschätzt werden. Danke noch einmal. – Budda

+4

@Budda Was ich glaube, ist, dass LBugnion sagt, dass das Konzept, das er für IDisposable verwendet hatte, bereits mit der Idee von GC das Objekt so schnell wie möglich überladen wurde. Viele von uns verwenden jedoch immer wieder das gleiche VM-Objekt, sodass ViewModelBase statt des Objekts ein ICleanUp-Interface erhalten hat, dessen Zweck es ist, den VM Clean zu löschen, damit er wieder verwendet werden kann. Dies kann nützlich sein, wenn Sie eine erste VM-Methode verwenden, WPF wird die Ansicht nicht wegwerfen und dann neu erstellen, stattdessen wird sie wie die VM gereinigt. – Agies

+0

Danke. Es ist jetzt klar – Budda

2

Ich denke, ich möchte etwas mit Laurent in diesem Punkt abweichen. Die Idee hinter IDisposable ist, dass das Objekt eine Bereinigung hat, die stattfinden muss und nicht per se etwas mit der Speicherbereinigung zu tun hat. Tatsächlich ist IDisposable in den meisten Fällen implementiert, um unmanaged Ressourcen wie Dateihandles, Synchronisierungsobjekte oder Datenbankverbindungen zu bereinigen, die außerhalb des Geltungsbereichs des GC liegen. Nur weil eine Basisklasse IDisposable implementiert, bedeutet das nicht, dass sie eine tatsächliche Implementierung haben muss. Dies kann in die virtuelle Methode Dispose (bool disposing) verlagert werden, die von abgeleiteten Klassen überschrieben werden kann, damit sie bereinigt werden können.

Das Problem, auf das Budda anspielt, ist, dass IDisposable per Konvention eine unidirektionale Operation ist. Sobald ein Objekt entsorgt wurde, sollte es eine ObjectDisposedException auf seine öffentlichen Methoden werfen. Wenn Sie nur die Ressourcen leeren möchten, damit Sie das Objekt wiederverwenden können, ist eine Bereinigungsmethode sinnvoll. Allerdings würde ich nicht unbedingt die Dispose-Funktionalität entfernen, die einem anderen Zweck dient.

+1

Nicht verwaltete Ressourcen müssen in der Finalize-Methode freigegeben werden. Sie können das System auch zwingen, sie während der Entsorgung freizugeben und in diesem Fall finalize zu unterdrücken (siehe Implementierungsmuster der "Dispose" -Methode) – Budda

2

"Interessante" kleine Geschichte: Programmierer in meinem Team hatten sich nicht von Veranstaltungen abgemeldet, ich habe IDisposable in unserer Ansichtsmodellhierarchie "gewaschen", um meine Meinung darüber, ob Dispose der richtige Ort war, zu ändern.

Unter bestimmten Umständen war es schwierig, Dispose wegen MEF und einigen anderen funky Weisen, die wir unsere Sichtmodelle erstellen, zu nennen. Das ließ mich fragen, ob es richtig war.Und dann ist da noch die Tatsache, dass Dispose eine gewisse Sorgfalt (und ein Ausschnitt) muss richtig machen:

DG Update: Dispose, Finalization, and Resource Management

Später habe ich auf einem WP7 App einige Wochenendarbeit haben (wo ich MVVM Licht verwenden) und bemerkte Laurents Änderung auch von Herzen.

Ich denke, es ist die richtige Entscheidung; IDisposable sendet eine Nachricht, dass der "Kunde" versuchen sollte, die Klassenverwendung in ein using() zu verpacken oder andernfalls die Hände der Instanz so schnell wie möglich zu waschen.

Ursprünglich stimmte ich der angenommenen Antwort in dem Thread unten zu, aber dann begann ich zu denken, dass JaredPar Recht hatte.

Using IDisposable to unsubscribe events

Luke