如何从ElementHost Control中清除memoryleak

时间:2014-07-18 10:41:45

标签: c# wpf elementhost

我需要在Winform用户控件上托管WPF控件。为此,我使用了ElementHost控件。当我运行Ants Memory分析器时,我知道ElementHost控件中存在大量内存泄漏。请在下面找到附加的保留图表,并帮助我修复Memoryleak。enter image description here

4 个答案:

答案 0 :(得分:1)

看起来像cachedLayoutEventArgs泄漏的某种已知的WinForms问题。根据我的经验,在Windows窗体中存在某些情况,当处置的控件可以缓存在LayoutEventArgs中时,它会阻止它被正确收集。有关详细信息,请查看Windows Forms Memory Leak主题。

我建议您在处置控件时明确调用PerformLayout()方法,包含ElementHost或跟随recomendation帖子中的WPF element host memory leak

答案 1 :(得分:0)

我首先要创建你自己的ElementHost,重写dispose,看看你是否能看到那些事件中的任何问题。寻找处理dispose时仍然处于闲置状态的处理程序。您可以取消注册dispose方法中的引用

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;
}

如果没有任何代码暗示提示,很难说问题出在哪里,但这将是一个不错的起点

答案 2 :(得分:0)

我遇到了完全相同的内存泄漏情况,并且症状完全相同。这是我处理情况的方式。

ElementHost类具有PropertyMap属性,该属性是将WinForms控件属性映射到WPF控件属性的集合。

在这种特殊情况下,内存通过保留MemoryStream实例的BackgroundImage泄漏。 因此,解决方案是删除BackgroundImage属性映射:

elementHost.PropertyMap.Remove("BackgroundImage");

答案 3 :(得分:0)

仅根据Vadim的回答进行扩展。我在TabbedControl上有一个ElementHost,每次我将其切换回时,都会发生内存泄漏。罪魁祸首BackgroundImage是罪魁祸首。对于遇到类似困境的人,以下解决方案:

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

GC.Collect可能过大了吗?不确定。