问题描述
我在Windows窗体上使用元素主机时发生了奇怪的内存泄漏。
我有一个主窗体,它将打开另一种窗体,该窗体仅具有elementhost控件(在这一点上,它没有wpf控件子级)。
只能打开1个主机表格。
每次打开表单时,应用程序内存都会增加20Mb,在关闭表单时这不是空闲的,因此,在多次打开主机表单后,内存不足!
现在,如果我从表单中删除元素宿主,则内存将保持稳定。
我一直在运行CLRProfiler和ANTS,但是我发现所有问题都在元素主机上,并且我还没有找到任何解决方法。
wpfHost是开箱即用的,只需将其从工具栏拖动到winForm。
知道我该如何解决吗?
解决方法
如果链接将再次断开,这是解决方法(复制粘贴)
KGy发表于22.10.2010在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对象(ѭ1是一个很好的示例)在Windows中注册以处理主题更改事件。 Windows拥有对它们的引用,因此它可以告诉用户是否更改了主题。令人讨厌的是,如果这些对象处于关闭状态,则它们不会注销,结果是它们的窗体被销毁了,但它们没有被注销。
那么,您如何销毁这些物体之一?对于ToolStripButton
,将case3ѭ设置为false
就可以了。事实证明,切换ѭ3也会切换控件是否处理主题更改事件。因此,如果将Visible
设置为false
,该控件将取消注册,然后当它超出范围时,它实际上可能会被销毁。
出于相同或相似的原因,也许对ѭ8会有所帮助。很难说出来,因为您会发现如果您深入研究此问题,就不会确切地记录在案。
, 我的表单上有一个WPFElementHost
对象,并且还注意到内存泄漏。我正在做的事情是这样的:
VAR cnt=this.MyHostControl.Child as MyWPFControl.WPObject;
并将在范围IE中执行此操作:
Private void Myfunction()
{
VAR cnt=this.MyHostControl.Child as MyWPFControl.WPObject;
cnt.Myproerty=\"Issue\";
}
我不是being12的忠实粉丝(想起以前的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
对象。
仍在测试中,它似乎可以正常工作。随着时间的流逝,我们将看到。