如何清除ElementHost控件中的内存泄漏问题。

6

我有一个需求,需要在Winform用户控件上托管WPF控件。为了实现这一点,我使用了ElementHost控件。当我运行Ants Memory profiler时,我发现ElementHost控件存在巨大的内存泄漏问题。请参考下面附加的保留图,并帮助我解决内存泄漏问题。enter image description here

4个回答

2
我遇到了完全相同的内存泄漏情况,出现了完全相同的症状。以下是我处理这种情况的方法。
ElementHost类有一个PropertyMap属性,它是将WinForms控件属性映射到WPF控件属性的集合。
在这种特殊情况下,内存泄漏是通过保持MemoryStream实例的BackgroundImage引起的。 因此,解决方案是删除BackgroundImage属性映射:
elementHost.PropertyMap.Remove("BackgroundImage");

你救了我的一命!我遇到了一个问题,我在TabControl上有一个ElementHost,每次我切换选项卡时,都会出现内存泄漏。结果发现这就是罪魁祸首!谢谢你,伙计!我曾经担心自己要进入一个痛苦的世界! - stigzler
我可以确认这一点,除了仅使用BackgroundImage并不能解决问题,我清除了整个属性映射:elementHost.PropertyMap.Clear() - Heinz Kessler

1
看起来像是WinForms中已知的缓存cachedLayoutEventArgs泄漏问题。根据我的经验,有些情况下在Windows Forms中,已释放的控件可能会被缓存到LayoutEventArgs中,这会阻止其正常回收。请参考Windows Forms Memory Leak线程了解详情。
我建议您在处理包含ElementHost的控件时,显式调用PerformLayout()方法,或者遵循WPF element host memory leak线程中的推荐操作

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

没有任何代码的情况下很难说问题出在哪里,暗示一下,但这可能是一个不错的起点


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可能有些过度了?不确定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接