WPF element host memory leak
Asked Answered
D

3

9

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?

Differentiate answered 16/6, 2011 at 14:50 Comment(0)
R
8

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;
}
Regelation answered 28/11, 2014 at 10:34 Comment(3)
Hey, I was wondering if you could explain me what's your elementHost object ? I've tried to replace it with my WindowsFormsHost object but the conversion of its child to FrameworkElement is not allowed.Teletypesetter
elementHost is System.Windows.Forms.Integration.ElementHost, which is placed inside a System.Windows.Forms.UserControlRegelation
Great. ElementHost memory are released.Vespers
C
2

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.

Chasten answered 16/6, 2011 at 16:5 Comment(2)
I have tried this with no luck. This is turning from a memory leak to a pain in the ass right now!Differentiate
Don't think of it as a pain in the ass. Think of it as an opportunity to learn how to use a memory profiler.Chasten
L
-1

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.

Lens answered 6/10, 2011 at 14:56 Comment(1)
This won't solve the problem. var is a local variable, and you've switched this to be an instance or static variable. This will never decrease the amount of time the object lives before being GC'd, and can increase it (depending on what you meant by "global object"). Plus the author of the question already figured out a solution to their problem...Zoology

© 2022 - 2024 — McMap. All rights reserved.