.NET 数据绑定和内存泄漏
Posted
技术标签:
【中文标题】.NET 数据绑定和内存泄漏【英文标题】:.NET data bindings and memory leak 【发布时间】:2013-02-13 23:22:51 【问题描述】:我的应用程序中存在内存泄漏,我找不到真正的来源。在名为DataTableEditor
的控件中有这行代码:
refreshButton.DataBindings.Add("Enabled", asyncSqlResultsViewer, "CanRefresh", true, DataSourceUpdateMode.Never);
asyncSqlResultsVewer
只是一个带有显示数据的DataGridView
的用户控件。用于异步加载数据,但现在不再加载。 DataTableEditor
控件是另一个包含AsyncSqlResultsVewer
的用户控件。泄漏似乎与此有关,因为它显示 PropertyDescriptor
作为保持对象活动的路径的一部分:
我是使用 .NET Memory Profiler 的新手,但问题是,删除上面的行可以消除泄漏。使用DataBindings.Remove
删除边界也可以修复泄漏。但是,这应该发生吗? asyncSqlResultsVewer
已被处置,据我所知与DataTableEditor
一起被取消引用,因此只要没有其他人引用它们中的任何一个(对吗?),它们中的每个引用都不应该让它们继续存在。我仍然可以删除绑定以防万一或作为黑客攻击,但我希望有人帮助我找出泄漏的真正原因是什么。
如果您怀疑这是实际的内存泄漏,应用程序会在打开和关闭多个显示大量数据的DataTableEditor
s 后崩溃。此外,分析器告诉我该对象已被释放,但仍有对其的引用。
如果有任何其他信息可以帮助您解决这个问题,请告诉我。
编辑:我想我知道泄漏可能来自哪里。上面的refreshButton
是这个类的一个实例:
public class ToolStripBindableButton : ToolStripButton, IBindableComponent, INotifyPropertyChanged
private ControlBindingsCollection dataBindings;
private BindingContext bindingContext;
public ControlBindingsCollection DataBindings
get
if (dataBindings == null) dataBindings = new ControlBindingsCollection(this);
return dataBindings;
public BindingContext BindingContext
get
if (bindingContext == null) bindingContext = new BindingContext();
return bindingContext;
set bindingContext = value;
public override Image Image
get return base.Image;
set SetImage(value);
private void SetImage(Image value)
if (base.Image != value)
base.Image = value;
OnPropertyChanged(new PropertyChangedEventArgs("Image"));
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(PropertyChangedEventArgs e)
if (PropertyChanged != null) PropertyChanged(this, e);
添加Dispose
覆盖并执行dataBindings.Clear()
可修复泄漏。这是我应该做的事情还是泄漏的真正原因仍在其他地方?
【问题讨论】:
如果您无法显示一些相关代码,这很难提供有效的答案..您是否有权访问相关源代码..? 我知道但不确定要显示什么 有太多可能与此相关的代码。 您正在添加绑定的 refreshButton 是否也超出范围并被释放?我想知道这是否是绑定本身的结果,因为有与之关联的事件,这将引用 DataGridView。 【参考方案1】:我相信您已经自己回答了内存泄漏问题。
在我看来,泄漏的来源似乎是刷新按钮(ToolStripBindableButton
的实例)。
当ToolStripButton.Dispose()
被调用时,它知道如何清理/释放所有需要的对象。但是它无法知道你是如何扩展类的,因此它不能帮助你清理。
我本来希望 ControlBindingsCollection
和 BindingContext
继承 IDisposable
从而明确需要清理。
protected override void Dispose(bool disposing)
base.Dispose(disposing);
if (disposing && dataBindings != null)
dataBindings.Clear();
dataBindings = null;
dindingContext = null;
PropertyChanged = null;
很难说您是否找到了问题的根源,但我会密切关注任何未以某种方式处理/释放/杀死的事件。
还要密切关注表单上的组件。 Theise 只有在使用 IContainer 实例创建时才会自动处理,并且 WinForms 设计者可以选择不这样做。
【讨论】:
以上是关于.NET 数据绑定和内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章
Silverlight + MVVM + 绑定 = 内存泄漏?