【问题标题】:Making Windows Forms controls read-only and IDisposable将 Windows 窗体控件设为只读且 IDisposable
【发布时间】:2009-09-06 06:57:16
【问题描述】:

我想将 Windows 窗体控件设为只读且 IDisposable。

这是好事还是坏事?调用 Dispose 时需要注意什么?

我有一个选项卡 (PageTab),我扩展并插入了一个具有列表视图和另一个工具栏控件的面板。然后将这些选项卡插入选项卡控件(所有本机 .NET Windows 窗体控件)。

当用户关闭这些选项卡之一时,我调用 Dispose 方法(它遵循 MSDN 实现 IDisposable 的方式)。

将控件声明为只读(见下文)是否明智或建议?

protected readonly ListView _AccountsList = new ListView();
protected readonly Panel _Panel = new Panel();

因为在 Dispose 方法中我只是对它们调用 _Panel.Dipose() 等,但我不能将它们设置为 null。我想尽可能避免泄漏并收集垃圾。

非设计师 GUI 开发和处置它们的最佳方式是什么?

【问题讨论】:

    标签: c# winforms listview panel idisposable


    【解决方案1】:

    Control.Dispose 的默认实现(由 TabPage 继承)就足够了。它迭代存储在 Controls 集合成员中的子控件并调用它们的 Dispose() 方法。你不必帮忙。

    只有两种情况需要显式调用 Dispose():

    • 从 Controls 集合中删除控件时。在这里调用 Dispose() 是一项硬性要求。不这样做将使窗口句柄在程序的生命周期内保持活动状态,它只是不可见。如果不处理,就会泄漏。
    • 当您使用 ShowDialog() 显示表单时。这绕过了表单及其子控件的正常自动处理,因此您可以回读对话框结果而不会冒 ObjectDisposed 异常的风险。 using 语句是执行此操作的正确方法。

    后一种情况实际上不是泄漏,Control 类的终结器确保对话框的窗口句柄最终被释放,假设没有对对话框对象的实时引用。

    Control 是少数几个忘记调用 Dispose() 实际上会导致无法控制的资源泄漏的类之一。您是正确的,因为您必须在您的 TabPage 派生对象上显式调用 Dispose() 才能在删除页面时释放它。但是您不必担心它的子控件。

    【讨论】:

      【解决方案2】:

      如果选项卡正在关闭,可能不会有任何其他对它的引用,因此您不必担心将值设置为 null。

      为了 GC 将变量设置为 null 的唯一值是在否则仍然存在对对象的实时引用的情况下。听起来好像不是这样。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-24
        • 1970-01-01
        相关资源
        最近更新 更多