C# Wie Sie sich Abmelden können alle event-Handler, der von einem bestimmten Ereignis?
Gibt es eine einfache Möglichkeit zu Durchlaufen, die alle über den Handler abonniert ein bestimmtes Ereignis? Mein problem ist, dass die Kunden abonnieren, aber vergessen abzumelden, so dass ein Speicher-Leck passiert. Ich brauche eine Weg für ein Objekt zu trennen, alle Handler, die Ereignisse, die in der Dispose-Methode, so ein Leck würde das nicht passieren - zumindest nicht wegen des events.
InformationsquelleAutor Adi Barda | 2010-03-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Set null, die zu Ihrer Veranstaltung:
MyEvent = null;
Aber es ist wirklich besser, um die clients Abmelden von Ihrer Veranstaltung.
Tatsächlich ist es möglich, wenn Sie innerhalb der Klasse, in der Veranstaltung erklärt wurde.
Sind Sie richtig.
Ist es nicht besser zu machen
MyEvent = new MyEvent()
?? dann bei der Anmeldung wieder bekommen Sie keine null-exception.Ereignis-Feld ist null, wenn niemand angemeldet ist, code, der ein Ereignis auslöst sollte man immer einen null-Wert überprüfen, bevor Sie Zugriff auf Ereignis
InformationsquelleAutor Andrew Bezzub
Ein alternativer Ansatz ist die Verwendung von sogenannten "schwachen delegieren" - Muster. Wenn Sie diese Technik verwenden, wird das Ereignis Referenzen Kunden nur mit
WeakReference
die nicht halten Sie Sie im Speicher. Die Kunden werden von der garbage Collection freigegeben, wenn Sie nicht mehr referenziert werden vom übrigen Teil der Anwendung (und der handler kann auch nicht registriert automatisch, wenn der client gesammelt).Dies ist in der Regel verwendet, um das problem zu lösen mit Kunden "vergessen", um ein Abonnement ein .NETZ-Ereignis, so dass es klingt wie diese wäre gut geeignet für dein problem.
InformationsquelleAutor Tomas Petricek
Memory leak passiert nur wenn ein anderes Objekt (listener) stirbt, bevor Sie Ihr Objekt (Quelle). In diesem Fall, Quelle, hält noch die Referenz zum listener, die verhindert, dass Zuhörer gesammelt werden. Wenn die Quelle stirbt, abgemeldet listener kann gesammelt werden, wie gut.
Wenn Quelle stirbt, bevor die Zuhörer bedeutet dies nicht, dass Zuhörer erhoben werden, die später, wenn alle anderen Referenzen auf null gesetzt werden.
Dies bedeutet, Quelle Dispose-Methode ist nicht der richtige Ort, um dieses problem zu lösen. Es kann gelöst werden, nur in einem listener-code. Einfach reden, Sie kann nichts tun, außer Fragen Sie Ihren Kunden schreiben sauberen code.
InformationsquelleAutor Alex F
In der Zeit des Schreibens, die Genaueste Antwort ist am wenigsten beliebt.
Können Sie bewirken den event-handler, aber das wäre sowieso gezappt, nachdem sein Besitzer gezappt - es ist nicht falsch zu sein, super sauber, aber wie Alex sagt, es ist nicht, wo das Problem ist.
Adi Quell-Klasse erlaubt das hören von Objekten gesammelt werden, wenn es sich selbst gesammelt ist, gibt es keinen Zweifel. Das problem ist also, dass Adi Quell-Objekt wird offen gehalten, eventuell durch einige lange Kette von Referenzen in seinem Kunden-code.
Den folgenden blog-post sieht auch eine Lösung, die Adi ist decribing und erklärt, warum es unnötig ist.
http://weblogs.sqlteam.com/mladenp/archive/2007/10/24/C-Care-about-Event-Memory-Leaks-with-Delegate.GetInvocationList.aspx
InformationsquelleAutor Luke Puplett