是否处置相当于处置其子女加上自己的面板?
在以下课程中:
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
拥有Panel
的Form
, Panel
控件及其所有子控件都将自动为您处理。 除非您动态地在表单中添加和删除实例,否则没有理由明确地为Panel
控件执行此操作。
这两个不完全相同,你可以通过使用Reflector查看Control.Dispose
的实现来轻松看到(当它仍然是免费的时很容易做到!)
例如,如果您只是在面板上调用Dispose,它将在每个子控件上调用DisposeAxControls,并在其子控件上调用Dispose之前将其自身从其父控件中删除。
尽管如此,我同意Cody Gray的看法 – 你需要弄清楚为什么它会冻结,而不是试图用你提议的解决方法“解决地毯下的问题”。
通常,您不会明确地调用Panel上的Dispose – 如果您这样做,则需要确保正确管理控件的生命周期和所有权。
要做的是逐步开始简化你的应用程序直到它不再冻结 – 找出导致冻结的原因(例如,通过删除你逐一提到的计时器 – 这听起来很可疑)。 一旦你有一个展示问题的非常简单的例子,你(或在这里的某个人)就可以更容易地计算出正在发生的事情。