2009-06-30 38 views
53

Wenn ich eine Anwendung mit nur wenigen Ereignisprozeduren registriert habe (und die Objekte, die die Ereignisse verwenden, werden nicht entfernt, bis die Anwendung geschlossen wird), muss ich mich wirklich sorgen, die Registrierung dieser Behandlungsroutinen aufzuheben? Der einzige gute Grund, den ich sehen könnte, ist, dass es einen zusätzlichen Overhead geben könnte, wenn Ereignisse ausgelöst werden, die Sie nicht unbedingt kümmern müssen (d. H. Sie haben mehrere Handler für ein Ereignis registriert). Gibt es noch einen anderen guten Grund? Jeder stieß auf größere Probleme, weil er die Ereignisse nicht abmeldete.Ist es schlecht, Ereignishandler nicht zu entfernen?

Antwort

68

Wenn Sie A ein Ereignis zu veröffentlichen, und B auf ein Ereignis abonnieren möchte (der Handler), dann ist es nur ein Problem, nicht abmelden, wenn A viel länger als B leben wird. Im Grunde bedeutet das Ereignisabonnement, dass AB immer noch sehen kann, also verhindern würde, dass es Müll gesammelt wird, und würde noch Ereignisse darauf feuern, selbst wenn Sie es vergessen haben (und vielleicht Disposed() es).

Zum Beispiel ist dies ein Problem, wenn A ein statisches Ereignis ist, und Ihre App läuft für eine Weile nach B stirbt ...

Es ist wichtig, zu beachten, könnte man fragen folgend:

Wenn B viel länger lebt als A, wird B verhindern, dass A Müll gesammelt wird?

Und die Antwort darauf ist "Nein". B hat keinen Bezug zu A während des Ereignisses; A wird wie üblich gesammelt

+0

Dies ist besonders schlecht, wenn B Ressourcen schwer ist ... –

+0

Great insight Marc. Handler für statische Ereignisse sind wirklich berüchtigt, wenn sie nicht beachtet werden, während sie den Teilnehmer entsorgen. – TheVillageIdiot

+3

Ich weiß, das ist ein alter Post und ich weiß nicht, ob es jemals gelesen werden wird, aber wenn B viel länger lebt als A, wird B verhindern, dass Müll gesammelt wird? –

14

Viele Leute scheinen zu denken, dass es nur wichtig ist, Ereignisse abzubestellen, wenn der Verleger den Abonnenten überleben wird. Ich mag diesen Ansatz nicht. Ein Ereignisteilnehmer, der sich nicht selbst vom Publisher löst, erzeugt einige unangenehme Abhängigkeiten vom Verhalten von Entitäten außerhalb des Publishers und Abonnenten. Wenn ein Verweis auf den Herausgeber länger als erwartet gehalten wird, hält dies den Abonnenten am Leben, zusammen mit allen Objekten, an denen der Abonnent eine Referenz hält. Wenn eine große Masse von abgebrochenen Objekten durch Ereignishandler miteinander verbunden ist, aber keine Live-Referenz zu einem von ihnen existiert, können alle Objekte vom Müllsammler erfasst werden. Wenn jedoch jemand irgendwo unerwartet einen Verweis auf eines der Objekte hält, kann dies verhindern, dass irgendwelche von ihnen als Müll gesammelt werden.

IMHO, es ist viel besser, proaktive entfernen Ereignishandler als sie zu verlassen und hoffe, dass alles aufgeräumt wird. Wenn man nicht sicher sein kann, dass es keine unerwarteten Verweise auf den Herausgeber geben kann, wird ein solcher Ansatz wahrscheinlich "meistens" funktionieren, aber gelegentlich Speicherlecks verursachen.

Verwandte Themen