2
Class ComponentsContainer   ' a component contains other components'
    Inherits System.ComponentModel.Component

    Private foo as New Component
    Private bar as New Component

Protected Override Sub Finalize()
    foo.Dispose()  ' HERE ? '
    bar.Dispose()
    MyBase.Finalize()
End Sub

Protected Overrides Sub Dispose(disposing As Boolean)
    If disposing Then
        foo.Dispose() ' OR HERE ? '
        bar.Dispose()
    End If
    MyBase.Dispose(disposing)
End Sub 
End Class
4

4 回答 4

3

您不应该(不必)从终结器中释放托管资源:

Protected Override Sub Finalize()
    ' foo.Dispose()  ' 
    ' bar.Dispose()  '
    MyBase.Finalize()
End Sub

因此,如果你的类没有非托管资源,你根本不需要终结器。

注意:您的班级缺少Public Sub Dispose()重载。

编辑:

由于foobar是托管资源(扩展组件),因此您只需要该Protected Overrides Sub Dispose(disposing As Boolean)方法。问题中的版本是正确的。并简单地删除Finalize().

于 2010-02-15T11:40:07.963 回答
3

终结器应该调用这个类的 Dispose,为 disposing 参数传递 false,而不是直接释放这个类拥有的对象。请参阅MSDN

编辑:所以要回答这个问题,应该在 Dispose 中处理拥有的对象,而不是 Finalize。

编辑 2:注意,这意味着如果对象在没有被释放的情况下被终结,那么 Dispose 只会被调用(通过 Finalize)使用“false”参数,并且子对象不会被此类释放。这是正确的,因为它们是托管对象,如果没有显式处置,它们将在框架感觉像时最终确定。

于 2010-02-15T11:42:27.407 回答
1

Dispose是当您明确想要在垃圾收集器释放对象之前释放一些资源时。

Finalize当或如果垃圾收集器开始释放对象时会自动调用。

如果您有许多对象保留资源,那么由于您不应该控制垃圾收集,您应该使用 Dispose。

从框架文档中:

请注意,即使您通过 Dispose 提供显式控制,您也应该使用 Finalize 方法提供隐式清理。Finalize 提供了一个备份,以防止在程序员未能调用 Dispose 时资源永久泄漏。

实施 Finalize 和 Dispose 以清理非托管资源

于 2010-02-15T11:45:50.130 回答
1

你继承什么?我怀疑它可能是System.ComponentModel.Container,直接或间接。

在这种情况下,您无需执行任何操作。System.ComponentModel.Container在其方法中自动处理它包含的任何组件。Dispose不用管它 - 这必须是实现处置/完成模式的最简单方法。

于 2010-02-15T12:13:37.610 回答