我正在使用Visual c#express 2010在c#中开发一个Windows窗体应用程序(.NET 4.0).我在释放分配给UserControls的内存时遇到了麻烦,我不再使用了.
我有一个FlowLayoutPanel,其中显示自定义UserControls.FlowLayoutPanel显示搜索结果等,因此必须重复更新显示的UserControl集合.
在创建和显示每个新的UserControl集之前,在我的FlowLayoutPanel的ControlCollection(Controls属性)中当前包含的所有控件上调用Dispose(),然后在同一ControlCollection上调用Clear().
这似乎不足以处理UserControls使用的资源,因为每个新的UserControls集都被创建并添加到我的ControlCollection中,我的UserControls似乎也没有被垃圾收集声明.应用程序的内存使用量在很短的时间内急剧上升,然后达到稳定状态,直到我显示另一个列表.我还用.NET Memory Profiler分析了我的应用程序,它报告了许多可能的内存泄漏(见下节).
我错了.问题是使用foreach构造迭代ControlCollection并在其控件上调用Dispose()导致的错误,Hans Passant在他的回答中描述了这个错误.
问题似乎是由我的UserControls中使用的ToolTip引起的.当我删除这些时,我的UserControls似乎被垃圾收集声明..NET内存分析器证实了这一点.我早期测试中的问题1和6(见下节)不再出现,并报告了一个新问题:
未释放的实例(释放资源和删除外部引用)7种类型的实例已被垃圾收集而未正确处理.请查看以下类型以获取更多信息.
ChoiceEditPanel(继承),NodeEditPanel(继承),Button,FlowLayoutPanel,Label,> Panel,TextBox
即使工具提示的参考已经消失,这不是一个长期的解决方案,但当我不再需要它时,仍然存在确定性地处理我的UserControls的问题.但是,并不像删除对工具提示的引用那么重要.
我使用一个名为NodesDisplayPanel的UserControl,它充当FlowLayoutPanel的包装器.这是我的NodesDisplayPanel类中的方法,用于清除FlowLayoutPanel中的所有控件:
public void Clear() {
foreach (Control control in flowPanel.Controls) {
if (control != NodeEditPanel.RootNodePanel) {
control.Dispose();
}
}
flowPanel.Controls.Clear();
// widthGuide is used to control the widths of the Controls below it,
// which have Dock set to Dockstyle.Top
widthGuide = new Panel();
widthGuide.Location = new Point(0, 0);
widthGuide.Margin = new Padding(0);
widthGuide.Name = "widthGuide"; …Run Code Online (Sandbox Code Playgroud) c# .net-4.0 visual-studio-2010 winforms visual-c#-express-2010