WPF元素主机内存泄漏
本文关键字:泄漏 内存 主机 元素 WPF | 更新日期: 2023-09-27 17:59:14
我在windows窗体上使用元素host时发生了一个奇怪的内存泄漏。我有一个主窗体,它打开了另一个窗体,这个窗体上只有elementhost控件(目前没有wpf控件的子窗体)。只能打开一个主机窗体。每次打开表单时,应用程序内存都会增加20Mb,当表单关闭时,这些内存是不可用的,所以,在多次打开主机表单后,我的内存就用完了!。现在,如果我从表单中删除元素host,那么内存将保持稳定。
我一直在运行CLRProfiler和ANTS,但我发现所有的问题都存在于元素主机上,我还没有找到任何解决方法。
wpfHost是开箱即用的,只需从工具栏拖动到winForm即可。
知道我该怎么解决这个问题吗?
如果链接将再次断开,这里是解决方案(复制粘贴)
由KGy于2010年10月22日6:12发布一种可能的解决方法:将以下代码放入包含ElementHost控件的控件/窗体的Dispose或其他发布方法中。
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
即可。事实证明,切换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
对象。
仍在测试中,看起来可能有效。随着时间的推移,我们会看到的。