是否处置相当于处置其子女加上自己的面板?

在以下课程中:

class MyPanel : Panel { ... protected override void Dispose(bool disposing) { // My code here } } 

以下两个代码示例是等效的吗?

 base.Dispose(disposing); 

VS

 if (disposing) { List ctrls = new List(this.Controls); this.Controls.Clear(); foreach(Control c in ctrls) { c.Dispose(); } } base.Dispose(disposing); 

如果它们有不同的效果,它会是什么?

编辑:我问这个是因为,无论出于何种原因,这样做是第一种方式冻结我的程序,然后处理它的任何子项( disposing是真的, Controls包含2个控件),而第二种方式工作正常。 如果我能愉快地使用第二个,那就太棒了。

是的,处理容器将自动处理其子控件。

根据MSDN文档 , Control.Dispose方法:

释放Control 及其子控件使用的非托管资源,并可以选择释放托管资源。

因此,在Panel控件上调用Dispose方法将自动处理其子控件。 然而,正如Joe的评论所指出的那样,有一个重要的警告:子控件必须取消订阅在父级范围之外声明的事件。 如果事件是将保持活动的对象的成员,它们将使子控件保持活动状态并防止它们被正确处理。 显然,您不需要取消订阅同时处理的对象中声明的事件,例如父级。

当然,这也可以扩展到Panel控件的容器(很可能是Form控件)。 每当您Dispose拥有PanelFormPanel控件及其所有子控件都将自动为您处理。 除非您动态地在表单中添加和删除实例,否则没有理由明确地为Panel控件执行此操作。

这两个不完全相同,你可以通过使用Reflector查看Control.Dispose的实现来轻松看到(当它仍然是免费的时很容易做到!)

例如,如果您只是在面板上调用Dispose,它将在每个子控件上调用DisposeAxControls,并在其子控件上调用Dispose之前将其自身从其父控件中删除。

尽管如此,我同意Cody Gray的看法 – 你需要弄清楚为什么它会冻结,而不是试图用你提议的解决方法“解决地毯下的问题”。

通常,您不会明确地调用Panel上的Dispose – 如果您这样做,则需要确保正确管理控件的生命周期和所有权。

要做的是逐步开始简化你的应用程序直到它不再冻结 – 找出导致冻结的原因(例如,通过删除你逐一提到的计时器 – 这听起来很可疑)。 一旦你有一个展示问题的非常简单的例子,你(或在这里的某个人)就可以更容易地计算出正在发生的事情。