小编Sim*_*owe的帖子

正确处理和删除对UserControls的引用,以避免内存泄漏

我正在使用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

14
推荐指数
1
解决办法
6374
查看次数