Wenn ich folgenden Code habe:
MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass = null;
Wird pClass Müll gesammelt? Oder wird es herumhängen und immer noch seine Ereignisse abfeuern, wenn sie auftreten? Muss ich Folgendes tun, um die Speicherbereinigung zu ermöglichen?
MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass.MyEvent -= MyFunction;
pClass = null;
c#
.net
event-handling
garbage-collection
Mark Ingram
quelle
quelle
Antworten:
Für die spezielle Frage "Wird pClass durch Müll gesammelt?": Das Ereignisabonnement hat keine Auswirkungen auf die Sammlung von pClass (als Herausgeber).
Für GC im Allgemeinen (insbesondere das Ziel): Es hängt davon ab, ob MyFunction statisch oder instanzbasiert ist.
Ein Delegat (z. B. ein Ereignisabonnement) für eine Instanzmethode enthält einen Verweis auf die Instanz. Ja, ein Event-Abonnement verhindert GC. Sobald jedoch das Objekt, das das Ereignis veröffentlicht (pClass oben), zur Erfassung berechtigt ist, ist dies kein Problem mehr.
Beachten Sie, dass dies eine Einbahnstraße ist. dh wenn wir haben:
dann wird "Herausgeber" "Ziel" am Leben erhalten, aber "Ziel" wird "Herausgeber" nicht am Leben erhalten.
Also nein: Wenn pClass trotzdem gesammelt werden soll, müssen die Listener nicht abgemeldet werden. Wenn pClass jedoch langlebig wäre (länger als die Instanz mit MyFunction), könnte pClass diese Instanz am Leben erhalten, so dass dies der Fall wäre notwendig sein, abmelden , wenn Sie das Ziel gesammelt werden sollen.
Aus diesem Grund sind statische Ereignisse jedoch sehr gefährlich, wenn sie mit instanzbasierten Handlern verwendet werden.
quelle
WeakReference
eine gute Idee , und in einigen Fällen könnte dies eine gute Idee sein, aber so oft wie nicht wird es eine starke sein.Ja, pClass wird Müll gesammelt. Das Ereignisabonnement bedeutet nicht, dass ein Verweis auf pClass vorhanden ist.
Und so nein, Sie müssen den Handler nicht trennen, damit pClass Müll gesammelt wird.
quelle
Sobald ein Speicher nicht mehr referenziert wird, wird er zum Kandidaten für die Speicherbereinigung. Wenn die Instanz Ihrer Klasse den Gültigkeitsbereich verlässt, wird sie von Ihrem Programm nicht mehr referenziert. Es wird nicht mehr verwendet und kann daher sicher gesammelt werden.
Wenn Sie nicht sicher sind, ob etwas gesammelt wird, stellen Sie sich folgende Frage: Gibt es noch einen Verweis darauf? Die Ereignishandler werden von der Objektinstanz referenziert, nicht umgekehrt.
quelle
pClass
wird Müll gesammelt. Wenn jedoch der obige Code innerhalb einer anderen Klasse Snippet ist, kann die Instanz dieser Klasse nicht gelöscht werden , wenn Sie nicht festgelegt haben ,pClass
umnull
.quelle