there is no doubted that event handler is the number one reason of memory leak under .NET framework.
recently I was part of a team which was tracing a memory leak out of a dump file, as expected the main issue was happens to be the prime suspect (event handler).
you can find plenty of resources on how and why careless usage of event handler can cause a memory leak (just Google it).
in this post I will present a general solution for this problem (which can be use when applicable).
the solution is to use some kind of weak reference abstraction over the event.
the weak event abstraction will allow the GC to collect the event handler’s instance even while it is subscribe to a rooted event (as long as the handler has no other rooted reference is will be collect).
you can download a sample solution from hear.
the solution is having 2 main parts,
WeakEvent and WeakEvent<T> which hold a similar implementation for EventHandler and EventHandler<T>.
I will shortly present the WeakEvent<T> but before that I want to present a usage of WeakEvent<T>.
suppose that you are having the following class which is having a single event called Notify:
in order of adding a correlate weak event to this class you should apply 3 simple steps:
line 3, adding a private field of WaekEvent or WaekEvent<T>.
lines 4-14, add an event abstraction which will route event’s subscription to the weak event;
at the class constructor, assign the weak event with 2 delegate that register an unregister from the original event.
Behind the cine
the root of this implementation is the HashSet<EquatableWeakReference> at line 5, which is used to keep a weak reference of the original subscribers.
EquatableWeakReference is a class which derive from WeakReference and handle equality and get hash code of the internal target (the class was written by Eli Arbel and it is part of the sample download).
because event is not a .NET first class citizen the constructor is getting 2 delegates (line 8) which will be use to register and unregister from the original event.
the heart of the implementation is at the event routing (lines 14-33), which maintain the weak reference data structure.
and a mediator event handler (line 35-49) which hook the original event and route the data into the weak subscribers.
finally a Dispose pattern is been used as a good .NET citizen.
when ever you are having an event handler which its lifetime doesn’t need to be dictate by the event source, it is better to have a week event relationship in order to avoid a memory leaks.
during the process of analyzing the memory leak and having a proper solution I was working with a few other developers and consultants, Oren, Eli and Roman, all was having an important contribution toward this solution.