Weak Event Target References
The exercise discussed in the .Net Memory Leaks post lead to the identification of a class of memory leak issues in the application being profiled. The class of memory leaks are as a result of an object being held in memory solely by its listing within an event handler. The object has no purpose existing other than being registered with an event handler when it did have a purpose in life. My conclusion is that it would be more beneficial to application development if event handlers only had weak references to the target objects that are called when the event fires (at least by default). One of the major benefits of .NET events is that the class exposing the event is loosely coupled from the class subscribing to the event. All that is common between the provider class and the subscriber class is the event handler delegate type and the event arguments class. This suggests that in most scenarios, the lifetimes of the provider instance and the subscriber instance should not be strongly linked.
Given my experience with the WeakReference class, it would have been useful if there some easy way of making a event only reference its subscribers using weak references. Based on this requirement, I did some research into what has already been done in that area. Some useful links are included below. They are date ordered to provide some context for the author’s words. Unfortunately its not a satisfying read as there doesn’t seem to be a standard way of dealing with this issue “automatically”.
Some authors take the view that the correct way of doing this is making sure that event unsubscription occurs in the FormClosing event of a Windows form or the Dispose method of an IDisposable. Sure this makes sense, but it takes away from the promise of developer productivity that is one of strengths of .NET. We leverage the garbage collector to deal with many of our memory management issues, why not include event subscriber dependencies? Some cursory analysis of the problem tends to suggest that the only real solution that is convenient to use and does not compromise performance would have to be done in a combination of the CLR, compiler and the core framework i.e. in Microsoft’s domain. For example the .NET 2.0 generics functionality won’t let you use EventHandler as a generic constraint. Even if it did, I’m not sure if EventHandler.Invoke( object sender, EventArgs args ) can be called on a delegate derived from EventHandler. Anyway here’s the list of links:
Jul 2003: http://weblogs.asp.net/fbouma/archive/2003/07/11/9980.aspx
Sep 2003: http://discuss.develop.com/archives/wa.exe?A2=ind0309c&L=dotnet-clr&D=0&T=0&P=17132
May 2004: http://blogs.msdn.com/greg_schechter/archive/2004/05/27/143605.aspx
June 2004: http://www.seedindustries.com/blog/x/2004_06_01_archive.html#108656795427367272
Jun 2004: http://www.interact-sw.co.uk/iangblog/2004/06/06/weakeventhandler
Jul 2004: http://weblogs.asp.net/fmarguerie/archive/2004/07/27/198489.aspx
Jan 2005: http://damieng.blogspot.com/2005/01/lapsed-listeners-memory-leaks-with.html
Feb 2005: http://www.bluebytesoftware.com/blog/CommentView,guid,0d89ec27-a914-4e06-8eac-8cb8d5879566.aspx
Mar 2005: http://wesnerm.blogs.com/net_undocumented/2005/03/clr_dinner.html
Oct 2005: http://www.codeproject.com/csharp/weakeventhandlerfactory.asp