Frage

Ich bin mit mehreren Mischung Verhaltensweisen und Trigger für eine Silverlight-Steuerung. Ich frage mich, ob es ein Mechanismus zum automatischen Abnehmen oder sicherzustellen, dass OnDetaching () für ein Verhalten oder Trigger aufgerufen wird, wenn die Steuerung nicht mehr verwendet werden (das heißt von der visuellen Struktur entfernt).

Mein Problem ist, dass es ein Speicherleck mit der Kontrolle, weil einer der Verhaltensweisen verwaltet wird. Das Verhalten abonniert zu einem Ereignisse auf einigem langlebigen Objekt in der Überschreibung OnAttached () und sollte von diesem Ereignisse in der OnDetaching () wurde abzumelden außer Kraft setzen, so dass er ein Kandidat für die Garbage Collection werden kann. Allerdings OnDetaching () nie immer genannt zu werden scheint, wenn ich die Kontrolle aus der visuellen Struktur entfernen ... die einzige Art, wie ich es passieren, bekommen kann, ist, indem sie ausdrücklich die problematischen Verhaltensweisen vor dem Entfernen die Kontrolle abgenommen und dann ist es richtig Müll gesammelt .

Im Moment ist meine einzige Lösung war eine öffentliche Methode in dem Code-Behind für die Steuerung zu schaffen, die alle bekannten Verhaltensweisen durchmachen können und lösen, die Garbage Collection zu Problemen führen würde. Es würde den Client-Code bis zu wissen, dies zu rufen, bevor die Steuerung von der Platte zu entfernen. Ich weiß nicht wirklich wie dieser Ansatz, so dass ich für einige automatische Art und Weise suchen, dies zu tun, dass ich mit Blick oder einem besseren Vorschlag.

public void DetachBehaviors()
{
     foreach (var behavior in Interaction.GetBehaviors(this.LayoutRoot))
     {
          behavior.Detach();
     }

     //continue detaching all known problematic behaviors on the control....
}
War es hilfreich?

Lösung

Was Sie in diesem Fall wirklich brauchen, ist nicht ein Weg, um automatisch zu lösen, sondern um sicherzustellen, dass die durch die lange gelebt Objekt gehalten Referenz halten das Verhalten nicht (und damit alles andere hat es einen Verweis auf) aus wird Müll gesammelt.

Dies wird durch die Implementierung eines Vermittler-Muster acheived. Das Konzept ist, dass Sie nicht dem langlebige Objekt geben einen Delegaten mit einem Hinweis auf Ihre Behaviour, Sie stattdessen eine Mediator-Klasse als go-between erstellen. Der Mediator wird an der langlebigen Objekte Veranstaltung und hält eine WeakReference auf das Verhalten. Wenn das langlebige Objekt löst das Ereignis, um die Vermittler überprüft, dass der WeakReference noch am Leben ist, wenn so ein Verfahren auf sie fordert die Veranstaltung zu übergeben. Wenn, wenn das Ereignis der Mediator Funde kommt, dass der WeakReference nicht mehr lebt es löst seine Event-Handler aus dem langlebigen Objekt.

Daher gibt es nichts, das Verhalten und die alles andere beteiligt vom Stoppen Müll alles, das gesammelt wird, eine sehr kleine Vermittler Instanz mit einem toten Referenz angebracht noch übrig ist an den langlebigen Objekt. Da diese Vermittler sind winzig repräsentieren sie nicht ein echtes Problem und selbst bei einem das nächste Mal das Ereignis ausgelöst wird verschwinden.

Zum Glück müssen Sie nicht über diese Sachen selbst andere bauen haben es bereits getan. Es ist die WeakEventListener genannt. Dieser Blog: Markier- "schwachen" Beitrag; Erweiterungen Speicherlecks machen verhindert mit WeakEventListener noch einfacher! eine ausgezeichnete Reihe von Links zum Thema hat.

Andere Tipps

Joost van Schaik bietet eine Alternative Art und Weise Referenzen von angeschlossenen Verhaltensweisen zu bereinigen, während das Problem mit dem Speicherverlust zu vermeiden. Es hängt von den Aufräumarbeiten zu tun Delegierten von belastetem und unbelastetem Ereignisse des AssociatedObject verwenden.

Er bietet auch einen Code-Schnipsel für Stubs für angebracht Verhalten zu erzeugen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top