【问题标题】:Where should I dispose managed object held by a form?我应该在哪里处理表单持有的托管对象?
【发布时间】:2012-07-09 20:19:36
【问题描述】:

如果我有一个拥有托管IDisposable 对象的表单,这些对象需要在表单的生命周期内保留(即类级别成员,也许是一个为了单元测试而包装和管理计时器的类),当我应该打电话给他们Dispose()吗?

为了这个问题(为了避免“GC将为您处理”类型的答案),我们还假设我需要调用额外的关闭逻辑,例如:

Buffer.Flush()
Buffer.Dispose()

我可以将它放在我的部分类 (Form.Designer.vb) 中 Dispose() 方法的现有实现中,但通常不赞成修改该类。

看来FormClosedDisposed 事件将是最佳选择。有什么理由选择一个而不是另一个?

【问题讨论】:

  • 如果它实现了IDisposable,您应该使用using 语句来包装资源的创建。
  • 如果我需要保留班级级别的成员,我不能这样做,可以吗? (编辑问题以添加此额外信息)
  • 不,您不能对字段执行此操作。您的问题尚不清楚这是一个领域。请_编辑并澄清。

标签: vb.net winforms dispose idisposable


【解决方案1】:

“正确”的方法是将 Dispose() 方法从表单的 Designer.vb 文件移动到表单的源代码文件并进行编辑。然而,这在 vb.net IDE 中很尴尬,它隐藏了该文件。您必须单击“显示所有文件”图标才能看到它。

使用 FormClosed 是错误的,当您的表单使用 ShowDialog() 显示时,它会过早地处理您的对象。检索对话框结果时可能会导致 ObjectDisposed 异常。

使用 Disposed 事件没问题。

【讨论】:

    【解决方案2】:

    在 C# winforms 中,我将 Dispose() 方法的实现从设计器移至代码隐藏文件。从来没有遇到过问题。我猜你可以在VB中做同样的事情。

    唯一重要的是保留处理Components 集合的代码。

    【讨论】:

      【解决方案3】:

      一般来说,您应该在安全的情况下尽快释放非托管资源,例如使用using 语句。与您习惯性地“以防万一”或完全不必要地保持资源可用相比,它通常使您的应用程序维护起来更安全,并且更不容易出现与资源生命周期相关的死锁和其他不当行为。

      但是,有时您出于性能原因需要“缓存”非托管资源,或者出于语义原因甚至需要保留一个资源(例如,一些用于 UI 级别互斥的有意锁定方案)。

      在这些情况下,从父对象的Dispose 调用Dispose 是一个很好的约定;在这种情况下,通过处理 Disposed 事件。

      FormClosed 风险更大,因为另一个处理程序可能会阻止关闭发生,或者父表单的处理程序代码可能会调用此表单的方法,并且您最终可能会使用已处置的资源。再加上在整个表单上直接调用 Dispose 时永远不会释放资源的风险。

      将任何代码放入FormClosed 的主要优点是“更健全”的操作环境,尤其是对父表单的访问。然而,这很少需要处置非托管资源。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-07
        相关资源
        最近更新 更多