WPF元素主机内存泄漏

我在Windows窗体上使用元素主机有一个奇怪的内存泄漏。 我有一个主窗体,它打开另一个窗体,一个只有元素主机控件的窗体(此时,它没有一个wpf控件子窗口)。 只能打开1个主机表单。 每次打开表单时,应用程序内存都会增加20Mb,当表单关闭时不会自由,因此,在打开主机表单几次后,我的内存耗尽! 现在,如果我从表单中删除元素主机,内存保持稳定。

我一直在运行CLRProfiler和ANTS,但我发现所有问题都存在于元素主机上,我没有找到任何解决方法。

wpfHost是开箱即用的,只是从工具栏拖到winForm。

知道怎么解决这个问题?

如果链接再次中断,这里是解决方案(复制粘贴)

KGy于2010年10月22日6:12发布可能的解决方法:将以下代码放入包含ElementHost控件的控件/表单的Dispose或其他release方法中。

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

.NET应用程序中“内存泄漏”的主要原因是事件处理程序。 如果对象A处理由对象B引发的事件,则对象A可能超出范围并且不会被销毁,因为即使您的代码没有保留对它的引用,对象B也会这样做。

在WinForms中,一些UI对象( ToolStripButton就是一个很好的例子)在Windows中注册以处理主题更改事件。 Windows拥有对它们的引用,以便它可以告诉用户用户是否更改主题。 令人讨厌的是,如果它们所处的表格关闭,这些对象不会取消注册,结果是它们的表单被破坏但是却没有。

那你怎么摧毁其中一个物体呢? 对于ToolStripButton ,将Visible设置为false就可以了。 事实certificate,切换Visible也会切换控件是否处理主题更改事件。 因此,如果将Visible设置为false ,则控件将取消注册,然后当它超出范围时,它实际上可能会被销毁。

由于相同或类似的原因,这可能对ElementHost有所帮助。 这很难说,因为你会发现如果你深入研究这个问题,你知道,并不完全记录在案。

我的表单上有一个WPF ElementHost对象,并注意到内存泄漏。 我在做什么是这样的:

 VAR cnt=this.MyHostControl.Child as MyWPFControl.WPObject; 

并将在范围IE中执行此操作:

 Private void Myfunction() { VAR cnt=this.MyHostControl.Child as MyWPFControl.WPObject; cnt.Myproerty="Issue"; } 

不是VAR忠实粉丝(提醒旧的COM时代),我决定创建一个像这样的全局对象:

 MyWPFControl.WPObject cnt = null; 

然后在FormLoad_EvenT()

我像这样初始化了对象cnt

 cnt = this.MyHostControl.Child as MyWPFControl.WPObject; 

现在我的参考看起来像这样:

 Private void Myfunction() { cnt=this.MyHostControl.Child as MyWPFControl.WPObject; cnt.Myproerty="Issue"; } 

而且我不需要创建var对象。

仍在测试,看起来它可能正常工作。 我们会看到一段时间。