[C#] Is it bad to not unregister event handlers?


Answers

Many people seem to think that it's only important to unsubscribe from events if the publisher is going to outlive the subscriber. I dislike that approach. An event subscriber which does not detach itself from the publisher creates some a nasty dependencies on the behavior of entities outside the publisher and subscriber. If a reference to the publisher is held longer than expected, that will keep the subscriber alive, along with any objects to which the subscriber holds a reference. If a large mass of abandoned objects are interconnected by event handlers, but no live reference exists to any of them, all the objects can be swept up by the garbage collector. If, however, someone somewhere unexpectedly keeps a reference to one of the objects, that may prevent any of them from being garbage-collected.

IMHO, it's much better to be proactive in removing event handlers than to abandon them and hope that everything gets cleaned up. Unless one can be certain that no unexpected references to the publisher can exist, such an approach is likely to 'mostly' work, but cause occasional memory leaks.

Question

If I have an application with only a few event handlers registered (and the objects using the events are not disposed until the application is closed), do I really need to worry about unregistering those handlers? The only good reason I could see is that there might be a little extra overhead if events are being fired that you dont necessarly care about (i.e you have multiple handlers registered to one event). Is there any other good reason to? Anyone run into major issues because they didnt unregister events?




Well, let's take the last question first. You can't reliably unsubscribe from an event that you've subscribed to directly with a lambda expression. You either need to keep a variable around with the delegate in (so you can still use a lambda expression) or you need to use a method group conversion instead.

Now as for whether you actually need to unsubscribe, it depends on the relationship between the event producer and the event consumer. If the event producer should live for longer than the event consumer, you should unsubscribe - because otherwise the producer will have a reference to the consumer, keeping it alive for longer than it should be. The event handler will also keep getting called for as long as the producer produces it.

Now in many cases that's not a problem - for example, in a form the button that raises the Click event is likely to live for about as long as the form on which it's created, where the handler is typically subscribed... so there's no need to unsubscribe. This is very typical for a GUI.

Likewise if you create a WebClient solely for the purpose of a single asynchronous request, subscribe to the relevant event and start the asynchronous request, then the WebClient itself will be eligible for garbage collection when the request has finished (assuming you don't keep a reference elsewhere).

Basically, you should always consider the relationship between the producer and the consumer. If the producer is going to live longer than you want the consumer to, or it's going to continue raising the event after you're no longer interested in it, then you should unsubscribe.




Do I need to Dispose to deregister events?

To your first question: Yes. B has a reference to A. That way A will live as long as B. This is a nice way to loose memory in a UI app if you e.g. register with an event like App.OnIdle.

To the second: At the end everything will be killed.




If B holds a reference to A, A will not get Garbage Collected unless B is also eligible for Garbage Collection.

You shouldn't need a Dispose method for this. Once B has no references pointing to it either, the Garbage Collector will be smart enough to dispose both B and A.

If they are both alive for the life of the application, you don't need to deregister the event.