2008-10-09 10 views
28

Ist es eine gute Übung, die Ereignisbehandlung über WeakReference zu implementieren, wenn dieses Ereignis das einzige Objekt ist, das die Referenz enthält, und wir das Objekt als Garbage Collection benötigen?WeakReference und Ereignisbehandlung

Als Argument dazu:

Leute sagen, dass, wenn Sie etwas subscribe es in Ihrer Verantwortung zu abmelden und Sie sollten es tun.

+0

Die Frage wird: Was sind die Chancen, dass dieses Ereignis ausgelöst wird, wenn das Objekt Müll gesammelt wird? Warum überhaupt eine WeakReference? –

+0

@Jon Limjap ohne eine schwache Referenz, ist das nicht Chance Null, weil das Ereignis verfolgt das Objekt und daher wird es nicht gesammelt werden? – fostandy

+0

@fostandy: Nein, der Herausgeber eines Events wird von Abonnenten nicht am Leben erhalten, es funktioniert nur umgekehrt. Um Abonnenten zu erlauben, ohne vorherige Abmeldung gekündigt zu werden, sollte man WeakReference verwenden. Siehe: http://StackOverflow.com/a/298276/134761 – angularsen

Antwort

-2

Während das, was Sie vorschlagen, löst eine Reihe von Problemen (Ereignisreferenzmanagement und Speicherleckprävention), ist es wahrscheinlich, eine neue Reihe von Problemen zu öffnen.

Ein Problem, das ich während des Ereignisbehandlungsprozesses sehen kann, wenn das Quellobjekt Garbage Collected ist (da es nur mit einer schwachen Referenz gehalten wurde), führt jeder Code, der auf das Quellobjekt zugreift, zu einer Nullreferenzausnahme. Sie können argumentieren, dass der Event-Handler entweder nicht auf das Source-Objekt zugreifen sollte oder eine starke Referenz haben muss, aber es kann argumentiert werden, dass dies ein schlimmeres Problem sein könnte als das, was Sie überhaupt versuchen zu lösen.

+1

Wenn CLR bereits einen Event-Handler ausführt, wird der Stack den Verweis auf "this" enthalten und Objekte werden nicht gesammelt. –

9

Schwache Delegatenmuster sollten in CLR vorhanden sein. Normale Ereignisse zeigen die Semantik "Benachrichtige mich, während du lebst", während wir oft "mich benachrichtigen müssen, während ich lebe". Es ist falsch, delegate auf WeakReference zu haben, weil delegate auch ein Objekt ist und selbst wenn recepient noch am Leben ist und eingehende Referenzen hat, wird delegate selbst nur von der WeakReference referenziert und sofort gesammelt. Ein Beispiel für die Implementierung finden Sie in this old post.

6

Schwache Referenzen in ihrem eigenen Recht, lösen das Problem nicht, wie der Delegat die Referenz enthält. In der Composite Application Library, die mit Prism ausgeliefert wird (www.microsoft.com/compositewpf), gibt es eine WeakDelegate-Klasse, die Sie aus der Quelle abrufen können. Das WeakDelegate verwendet grundsätzlich die Reflektion und erstellt einen Delegierten nur für einen bestimmten Zeitpunkt und gibt ihn dann frei, wodurch er keine Zeiger hält. Innerhalb von CAL wird es von der EventAggregator-Klasse verwendet, aber Sie können es für Ihre eigene Verwendung freigeben, wie es unter MS-PL ist.

13

Es ist gut, sich die Angewohnheit zu nehmen, sich von Ereignissen abzumelden, wenn Sie können, aber manchmal gibt es keine offensichtliche "Aufräum" -Methode, wo es gemacht werden kann. Wir haben kürzlich eine blog article zu diesem Thema veröffentlicht; Es enthält Methoden, die das Abonnieren eines Events mit WeakReference erleichtern.