【问题标题】:How deep does Controls.Clear() clean up?Controls.Clear() 清理的深度有多深?
【发布时间】:2013-03-23 11:41:12
【问题描述】:

我正在使用TableLayoutPanel,它动态填充了其他TablelayoutPanels

现在我想知道当我在动态填充的TableLayoutPanel 上调用TableLayoutPanel.Controls.Clear 时会发生什么。显然,所有的子布局都被删除了,但是他们的孩子呢?它们是否也被妥善处理,还是我需要担心内存泄漏?

在调用Clear()之前我应该​​递归删除孩子的孩子吗?

【问题讨论】:

  • 如果没有其他对象持有对它们的引用,则被 GC'ed。
  • 对,但我想知道,Sub-Tablelayoutpanel 包含对其子项的引用,而子项包含对其父项的引用。我如何确保 GC 始终正确删除它们

标签: c# winforms tablelayoutpanel


【解决方案1】:

Clear 不释放控件,导致内存泄漏。从链接:

调用 Clear 方法不会从内存中删除控制句柄。 您必须显式调用 Dispose 方法以避免内存泄漏。

由于在循环中处理会弄乱索引,因此您可以将控件集合复制到另一个列表并对其执行ForEach 循环或使用向后的For 循环。

 for (int i = myTableLayoutPanelControls.Count - 1; i >= 0; --i) 
    myTableLayoutPanelControls[i].Dispose();
  

调用Dispose 将从内存中删除控件(当 GC 拾取它时)。这也将处理子控件的Dispose 方法的调用。

一个问题是,如果您有一个实现 IDisposable 的自定义控件,或者您在不调用 base 方法的情况下覆盖了 Dispose 方法。在您的对象的 Dispose 方法中,您需要确保您已取消订阅您范围之外的任何事件。如果您不这样做,该引用将使您的对象保持活动状态。

【讨论】:

    【解决方案2】:

    你的问题有点混乱。 Clear() 将删除引用,对象将被垃圾收集器收集。

    但是,您也使用了dispose 这个词。清除的对象将不会被释放,因为它们的Dispose 方法将被调用。

    因此,如果您不再使用这些对象,并且希望在它们上调用 Dispose,则必须自己进行。

    【讨论】:

    • 好的,那么问题是我应该对我不再使用的每个对象调用 dispose 还是让 gc 将其删除是否可以。我想不出 Dispose 方法所做的对刚才的程序至关重要的事情。另外,我之前评论的问题仍然存在,因为父母和孩子互相引用,GC会收集它们吗?
    • 是的,我在发布上述评论之前做了我应该做的事情——研究。如果我正确理解了 MSDN,则可以显式调用 Dispose 方法并释放非托管资源,GC 使用 finalize 方法隐式执行的操作(如果可用)。但是,正如keyboardP 所说,Clear 不会清除所有引用,因此我必须明确调用 Dispose。
    • @Xaser Clear 将清除控件内部的所有引用。它不会影响您在代码中拥有的引用。 Finalize 不能保证被调用,这就是为什么你必须调用Dispose 如果你想确定所有非托管资源都被清理了。
    猜你喜欢
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 2017-09-17
    • 2019-04-08
    • 2011-05-29
    • 2011-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多