views:

170

answers:

4

In one class, ClassA, I have a timer object. In this class I register the event handlers for the timer elapsed event. In another class, ClassB, I have a public event-handler for the timer elapsed event. So I register the event-handler from ClassB in ClassA as follows:

myTimer.Elapsed += ClassBInstance.TimerElapsed

What happens if I were to create a new instance of ClassBInstance and the timer elapsed event fires when the previous instance of ClassB's event-handler is still tied to the Elapsed event of the timer?

For example:

ClassB classBInstance = new ClassB();
myTimer.Elapsed += classBInstance.TimerElapsed

classBInstance = new ClassB();
myTimer.Elapsed += classBInstance.TimerElapsed
+9  A: 

AFAIK, ClassBInstance is not garbage collected as long as there are events registered, because the event holds a reference to it.

You have to make sure that you unregister all events of instances that are no longer in use.

Important are cases where the registered instance is IDisposable, because the event could be fired when the instance is disposed. In this cases I found it easiest to let the instance register itself, and unregister in Dispose.

Stefan Steinegger
Indeed. In particular, this is why static events are so dangerous; it is very easy to keep a vast number of objects alive if you don't unsubscribe religiously. At least instance events die with the instance that holds the backing field - but no GC for statics.
Marc Gravell
It's also worth mentioning that WPF jumps through hoops to avoid this with WeakEvents which IMHO are too complicated and in need of some language support.
Josh Einstein
+2  A: 

If the previous instance is still alive, and the new instance has also hooked up an event handler, the event will trigger both handlers (one at a time). It's important to to keep track of when you attach event handlers to events, that you also detach them when they are no longer needed. Otherwise the old instances will continue to live in memory, executing event handlers that may lead to unexpected results.

Fredrik Mörk
+3  A: 

Events are implemented such that as long as your publisher is alive all subscribers will be kept alive by the publisher even if you don't hold any other references to these.

Of course this also implies, that you must detach subscribers, if you want them to be cleaned-up independently of the publisher.

Brian Rasmussen
A: 

You could use my WeakEventHandler, based on WeakReference. Since it keeps a weak reference to the event listener, it doesn't force the listener to live.

see this answer

oɔɯǝɹ