Category Archives: .Net

WPF possible memory leak with EventManager.RegisterClassHandler

In the project I’m currently working on, I’m using the DataGrid from the WPF toolkit (that will be part of .Net 4.0 btw). Because I needed to tweak its behavior for copy/paste operations, I created a new class, PropertyDataGrid that inherits the DataGrid of the toolkit (you’ll notice that this time I used inheritance and not simply an attached behavior :p). In my DataGrid, I needed to register an event handler to be notified when a key is pressed in a DataGridCell. They are several ways to accomplish that:

  • If you’re tied to a XAML file (with a UserControl for instance) you can use an EventSetter
  • If you’re using a class that derives from ItemsControl you can override the GetContainerForItemOverride and IsItemItsOwnContainerOverride method to make the control uses your sub class (for example a CustomListBox that uses CustomListBoxItem) and do the job in the sub class (CustomListBoxItem)

Because those 2 approaches weren’t good in our case, we used the EventManager class that is very useful for this kind of operations. In one line of code, you can register an EventHandler for any RoutedEvent of any class:

public PropertyDataGrid()
{
    EventManager.RegisterClassHandler(
        typeof(DataGridCell), 
        PreviewKeyDownEvent, 
        new KeyEventHandler(this.OnCellPreviewKeyDown));
}

I wrote this code a couple of months ago. Then, a tester explained me that the memory used by our window was never reclaimed. Because the user can open several windows, the memory of the application was growing very quickly.

After spending a couple of hours tracking this memory leak, I found out that it was the call to RegisterClassHandler that was causing the leak. Using a non-static method (OnCellPreviewKeyDown) was causing the EventManager to keep a reference to the PropertyDataGrid control. This strong reference prevented the control for being garbage collected.

The solution was quick and easy; we just make the method static and initialize the handler in the static constructor. This way the delegate does not have a reference to the instance of the control, and can be kept by the EventManager without causing the leak:

static PropertyDataGrid()
{
    EventManager.RegisterClassHandler(
        typeof(DataGridCell), 
        PreviewKeyDownEvent, 
        new KeyEventHandler(OnCellPreviewKeyDown));
}

And voila ! We move from a solution eating always more memory to something reasonable:

before
after

Even using tools such a Memory Profiler, it was difficult to find the source of the leak, but at least, now, I’ll use carefully the EventManager class.

Note that of course you can have memory leak problems too if you don’t unregister your event handlers properly. If you want more information about that you can check out this article on CodeProject.

.Net4, WPF4 and VS2010 interesting links

Since the release of VS2010 last week a lot of cool blog posts had been written. The thing is more than VS2010 itself, the Beta1 comes with .Net4 and WPF4 too, and that’s exciting too !

Because I didn’t have time yet to write my own feedback, I’m sharing some links I found the last couple of days.

Download

  • A full list of what is available to download (VS2010, .Net framework…) can be found here.

MSDN Documentations

  • .Net Framework4 Beta1: here
  • What’s new in .Net Framework4 Beta1: here
  • WPF4 Beta1: here
  • What’s new in WPF4 Beta1: here
  • VS2010 Beta1: here
  • What’s new in VS2010 Beta1: here

From Beta1 to Beta1 and RTM

  • Jaime Rodriguez wrote a very nice article today and share his “insider view” of what’s on the road to RTM.
  • Karl Shifflet explained on his blog what’s going to change in the DataBinding pipeline (no more dummy converter !)

Channel9

  • Interviews of WPF and Silverlight program managers.
  • Rob Releya is also talking on the new XAML stack available in the framework. More information can be found on his blog.

Other bloggers

And also, Blend3

  • Unni’s wrote an article about updates that had been made to Blend regarding user feedback on Connect.