繁体   English   中英

绑定会在 WPF 中造成内存泄漏吗?

[英]Can bindings create memory leaks in WPF?

我是否需要在项目消失时解除绑定以防止内存泄漏? 我想我只是有点担心,如果我重新加载并将新模板应用于控件,并且在该模板中存在与外部元素的绑定,是否会阻止为模板制作的控件被垃圾收集?

如果您没有绑定到DependencyProperty或实现INotifyPropertyChanged的对象,则绑定可能会泄漏内存,并且您必须在完成后解除绑定。

这是因为如果对象不是DependencyProperty或未实现INotifyPropertyChanged则它会通过PropertyDescriptors AddValueChanged方法使用ValueChanged事件。 这会导致 CLR 创建从PropertyDescriptorobject的强引用,并且在大多数情况下,CLR 将在全局表中保留对PropertyDescriptor的引用。

因为绑定必须继续监听变化。 当目标仍在使用中时,此行为使PropertyDescriptorobject之间的引用保持活动状态。 这可能导致objectobject引用的任何object的内存泄漏,这包括数据绑定目标。

所以简而言之,如果您绑定到DependencyPropertyINotifyPropertyChanged对象,那么您应该没问题,否则像任何订阅的事件一样,您应该取消订阅您的绑定


编辑:有可能在 .NET4.5 中使用弱事件/引用修复了这个问题,但是经过几次快速测试后,我觉得还是一样,我将不得不更深入地进行确认,所以我个人会说in可能会在 4.5 中修复:)

不假装回答,仅供参考。 在一篇关于Finding Memory Leaks in WPF-based applications的经典文章中,作者Jossef Goldberg详细描述了 WPF 应用程序中可能存在内存泄漏的情况。 确实,大多数都与 .NET 3.5/4.0 相关,但有些情况可能与今天有关。 另外,有一个小的扩展名

关于Binding泄漏的引用:

Cause:

这个泄漏记录在这篇知识库文章中 它被触发是因为:

TextBlock控件绑定到一个对象 (myGrid),该对象具有对TextBlock的引用(它是 myGrid 子项之一)。

Note:这种类型的数据绑定泄漏对于特定场景(而不是所有数据绑定场景)是独一无二的,如知识库文章中所述 Path的属性不是DependencyProperty ,也不是实现INotifyPropertyChanged的类,此外必须存在强引用链。

代码:

myDataBinding = new Binding("Children.Count");
myDataBinding.Source = myGrid; 
myDataBinding.Mode = BindingMode.OneWay;
MyTextBlock.SetBinding(TextBlock.TextProperty, myDataBinding);

同样的泄漏代码也可以用 XAML 编写:

<TextBlock Name="MyTextBlock" 
           Text="{Binding ElementName=myGrid, Path=Children.Count}" />

Fix/Workaround:

有几种方法,最简单的方法是在窗口即将关闭时清除绑定。

例如:

BindingOperations.ClearBinding(MyTextBlock, TextBlock.TextProperty);

另一种方法是将数据绑定的模式设置为 OneTime。 有关其他想法,请参阅知识库文章

有用的链接:

使用 DataBinding 避免 WPF 内存泄漏

http://msdn.microsoft.com/en-us/library/aa970850.aspx ,WPF 使用弱事件模式,它不持有对对象的强引用,如果它们是对一个东西。

“WPF 数据绑定的许多方面已经在事件的实现方式中应用了弱事件模式。”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM