I'm having a strange memory leak using element host on windows forms.
I have a main form, which opens another form, the one that only haves the elementhost control on it (which, at this point, does not have a wpf control child).
Only 1 host form can be opened.
Every time I open the form, the application memory raises by 20Mb, which are not free when the form is closes, so, after opening the host form several times, I run out of memory!.
Now, if I remove the element host from the form, the memory remains stable.
I have been running CLRProfiler and ANTS, but I have found that all the problem resides on the element host, and I haven't found any workaround for this.
The wpfHost is used out-of-the-box, just dragged from the toolbar to the winForm.
Any idea how can I solve this?
if the link will break again, here is solution (copy-pasted)
Posted by KGy on 22.10.2010 at 6:12
A possible workaround:
Put the following code into the Dispose or another release method of your control/form that contains the ElementHost control.
if (elementHost != null)
{
FrameworkElement fe = elementHost.Child as FrameworkElement;
if (fe != null)
{
// Memory leak workaround: elementHost.Child.SizeChanged -= elementHost.childFrameworkElement_SizeChanged;
SizeChangedEventHandler handler = (SizeChangedEventHandler)Delegate.CreateDelegate(typeof(SizeChangedEventHandler), elementHost, "childFrameworkElement_SizeChanged");
fe.SizeChanged -= handler;
}
elementHost.Child = null;
base.Dispose(disposing);
elementHost.Dispose();
elementHost.Parent = null;
elementHost = null;
}
The primary cause of "memory leaks" in .NET applications is event handlers. If object A handles an event raised by object B, object A can go out of scope and it won't be destroyed, because even though your code doesn't retain a reference to it, object B does.
In WinForms, some UI objects (ToolStripButton
is a good example) register with Windows to handle theme-change events. Windows holds a reference to them so that it can tell them if the user changes the theme. Annoyingly, these objects don't unregister if the form they're on closes, with the result that their form gets destroyed but they don't.
So how the heck do you destroy one of these objects? In the case of ToolStripButton
, setting Visible
to false
does the trick. It turns out that toggling Visible
also toggles whether or not the control handles theme-change events. So if you set Visible
to false
, the control unregisters, and then when it goes out of scope it actually can get destroyed.
Maybe that will help with ElementHost
, for the same or a similar reason. It's hard to tell, because as you'll find if you dig into this issue, it's not exactly, you know, documented.
I have a WPF ElementHost
Object on my form and noticed a memory leak as well. What I was doing was something like this:
VAR cnt=this.MyHostControl.Child as MyWPFControl.WPObject;
and would do this in scope IE:
Private void Myfunction()
{
VAR cnt=this.MyHostControl.Child as MyWPFControl.WPObject;
cnt.Myproerty="Issue";
}
Not being a big fan of a VAR
(Reminds of old COM days), I decided to create a global object like this:
MyWPFControl.WPObject cnt = null;
Then on the FormLoad_EvenT()
I initialized the object cnt
like so:
cnt = this.MyHostControl.Child as MyWPFControl.WPObject;
Now my reference looks like this:
Private void Myfunction()
{
cnt=this.MyHostControl.Child as MyWPFControl.WPObject;
cnt.Myproerty="Issue";
}
And I do not need to create a var
object.
Still testing and it looks like it maybe working. We will see over time.