How to clear memoryleak from ElementHost Control
Asked Answered
U

4

6

I have a requirement to host WPF Control on Winform User control. To achieve this I used ElementHost control. When I run Ants Memory profiler , I got know that There is a Huge memory leak in the ElementHost control. Please find the attached retention graph as below and kindly help me to fix the Memoryleak .enter image description here

Unquestionable answered 18/7, 2014 at 10:41 Comment(0)
G
2

I ran into exactly same memory leaking situation with exactly same symptoms. Here's how I handled the situation.

ElementHost class have PropertyMap property which is collection that maps WinForms control property to WPF control property.

In this particular case, memory is leaking through BackgroundImage that keeps MemoryStream instance. And so, the solution is to remove BackgroundImage property mapping:

elementHost.PropertyMap.Remove("BackgroundImage");
Gonococcus answered 19/9, 2019 at 11:48 Comment(2)
you saved my bacon! I was having a problem where I had an ElementHost on a TabControl + every time I tabbed out and back, I would get a memory leak. Transpires this was the culprit! Thanks fella! I was worried that I was entering a world of pain!Frequency
I can confirm this, except that BackgroundImage alone did not do the trick, I cleared the whole Property map: elementHost.PropertyMap.Clear()Abigailabigale
A
1

It looks like a some kind of known WinForms issue with cachedLayoutEventArgs leak. From my experience there are some situation in Windows Forms when disposed controls can be cached within the LayoutEventArgs and it prevents it from being collected properly. Take a look at Windows Forms Memory Leak thread for details.

I suggest you try to call the PerformLayout() method explicitly when disposing control, containing your ElementHost or follow the recomendation from the WPF element host memory leak thread.

Auriscope answered 17/3, 2015 at 12:3 Comment(0)
C
0

I would start with creating your own ElementHost, override dispose, and see if you can see any issues in the events there. Look for handlers that are still lying around when dispose gets called. You can unregister the references in the dispose method

public class MyElementHost : ElementHost
{
    protected override void Dispose(bool disposing)
    {
         base.Dispose(disposing);
         if(disposing)
         {
             //Use debugging tools to identify handlers and unregister
             MyEventHandler myEventHandler = (MyEventHandler)Delegate.CreateDelegate(typeof(MyEventHandler), this, "childElement_MyLeakingEvent");
             FrameworkElement fe = Child as FrameworkElement;
             if(fe != null)
                fe.MyLeakingEvent -= myEventHandler;
         }
    }
    Child = null;
    Parent = null;
}

It is tough to say where the problem is without any code hint hint, but this would be a decent place to start

Cutch answered 17/3, 2015 at 19:42 Comment(0)
F
0

Just to expand upon Vadim's answer. I had an ElementHost on a TabbedControl and every time I tabbed back into it, i would get a memory leak. Transpires BackgroundImage was the culprit. Solution below for anyone who finds themselves in a similar predicament:

Private Sub BrushesEH_VisibleChanged(sender As Object, e As EventArgs) Handles BrushesEH.VisibleChanged

    If BrushesEH.Visible = False Then
        BrushesEH.PropertyMap.Remove("BackgroundImage")
        GC.Collect()
    Else
        BrushesEH.PropertyMap.Reset("BackgroundImage")
        GC.Collect()
    End If

End Sub

The GC.Collects are probably overkill? Not sure.

Frequency answered 16/3, 2020 at 23:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.