ChatGPT解决这个技术问题 Extra ChatGPT

Do event handlers stop garbage collection from occurring?

If I have the following code:

MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass = null;

Will pClass be garbage collected? Or will it hang around still firing its events whenever they occur? Will I need to do the following in order to allow garbage collection?

MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass.MyEvent -= MyFunction;
pClass = null;
I'm going to tentatively suggest to readers interested in this question that it might be worthwhile getting familiar with lightweight events / weak event patterns, which DON'T prevent garbage collection from occurring. A good SO bootstrap to this topic is stackoverflow.com/questions/185931/…
Note for posterity: setting the reference to null simply delays the garbage collector by extending by one line the scope of the reference. .NET is not VB6.

M
Marc Gravell

For the specific question "Will pClass be garbage collected": the event subscription has no effect on the collection of pClass (as the publisher).

For GC in general (in particular, the target): it depends whether MyFunction is static or instance-based.

A delegate (such as an event subscription) to an instance method includes a reference to the instance. So yes, an event subscription will prevent GC. However, as soon as the object publishing the event (pClass above) is eligible for collection, this ceases to be a problem.

Note that this is one-way; i.e. if we have:

publisher.SomeEvent += target.SomeHandler;

then "publisher" will keep "target" alive, but "target" will not keep "publisher" alive.

So no: if pClass is going to be collected anyway, there is no need to unsubscribe the listeners. However, if pClass was long-lived (longer than the instance with MyFunction), then pClass could keep that instance alive, so it would be necessary to unsubscribe if you want the target to be collected.

Static events, however, for this reason, are very dangerous when used with instance-based handlers.


Well, if the question is "will pClass be garbage collected", then the answer "it depends whether..." is not actually correct. It does not depend on anything, as Marc himself notes further down.
@Tor - fair enough - I'll clarify
Although an event subscription delegate only points one way, a subscriber which has any intention of unsubscribing from an event when done with it will need some form of reference to the publisher. It could be a WeakReference, and in some cases that might be a good idea, but as often as not it will be a strong one.
A great answer because it also addresses the other half of the question (that wasn't asked): the publisher will stop the subscriber from being GC'd.
Yes, and as @BobSammers said, It could really be a problem if a short-life instance, like a Form/Window, is subscribing to a long-life service like a Singleton that provides data for example : the Singleton then keeps a reference, and objects are thefore kept in memory even when we think they are unloaded ! So be very cautious when using Events. We abused with events for our big software, and it is very hard to solve afterwards.
S
Sabuncu

Yes, pClass will be garbage collected. The event subscription does not imply that any reference exists to pClass.

So no, you will not have to detach the handler in order for pClass to be garbage collected.


l
lvaneenoo

The moment a piece of memory is no longer referenced it becomes a candidate for garbage collection. When the instance of your class goes out of scope, it is no longer referenced by your program. It is no longer used and therefore can be safely collected.

If you are not sure wether something will get collected ask yourself the following question: does there still exist a reference to it? The event handlers are referenced by the object instance, not the other way around.


P
Picrofo Software

pClass will be garbage collected. However, if the code snippet above is inside another class, the instance of that class might not be cleared if you do not set pClass to null.