5

我需要在 Winform 用户控件上托管 WPF 控件。为此,我使用了 ElementHost 控件。当我运行 Ants Memory profiler 时,我知道 ElementHost 控件中存在巨大的内存泄漏。请在下面找到随附的保留图,并帮助我修复 Memoryleak 。在此处输入图像描述

4

4 回答 4

1

它看起来像是某种已知的 WinFormscachedLayoutEventArgs泄漏问题。根据我的经验,在 Windows 窗体中存在一些情况,当处置的控件可以缓存在其中时LayoutEventArgs,它会阻止它被正确收集。查看Windows 窗体内存泄漏线程了解详细信息。

PerformLayout()我建议您在处理控件时尝试显式调用该方法,包含您的ElementHost或遵循WPF 元素主机内存泄漏线程的建议

于 2015-03-17T12:03:33.197 回答
1

我遇到了完全相同的内存泄漏情况,症状完全相同。以下是我处理这种情况的方法。

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

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

elementHost.PropertyMap.Remove("BackgroundImage");
于 2019-09-19T11:48:54.543 回答
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;
}

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

于 2015-03-17T19:42:01.057 回答
0

只是为了扩展瓦迪姆的答案。我有ElementHost一个 TabbedControl ,每次我回到它时,我都会遇到内存泄漏。蒸腾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

s可能是GC.Collect矫枉过正?没有把握。

于 2020-03-16T23:06:43.433 回答