实施Dispose或Finalize?

时间:2010-02-15 11:35:43

标签: vb.net dispose finalizer

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 个答案:

答案 0 :(得分:3)

您不应该(不必)从Finalizer处理托管资源:

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

由此可见,如果您的班级没有非托管资源,则根本不需要终结器。

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

编辑:

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

即可

答案 1 :(得分:3)

终结器应该调用此类'Dispose为disposing参数传递false,而不是直接处理此类拥有的对象。请参阅MSDN

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

编辑2:注意,这意味着如果对象在没有处理的情况下完成,那么Dispose只会被“false”参数调用(通过Finalize),并且子对象不会被这个班级处理。这是正确的,因为它们是托管对象,并且如果没有明确处理,框架会感觉像是最终确定的。

答案 2 :(得分:1)

Dispose是在垃圾收集器释放对象之前明确要释放某些资源的时候。

当垃圾收集器绕过以释放对象时,会自动调用

Finalize

如果有许多对象可以保留资源,那么因为你不应该控制垃圾收集,所以你应该使用Dispose。

来自框架文档:

  

请注意,即使您提供   通过Dispose进行显式控制,   你应该提供隐式清理   使用Finalize方法。最终确定   提供备份以防止资源   从永久性泄漏,如果   程序员无法调用Dispose。

Implementing Finalize and Dispose to Clean Up Unmanaged Resources

答案 3 :(得分:1)

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

在这种情况下,您无需执行任何操作。 System.ComponentModel.Container automatically在其Dispose方法中处理它包含的任何组件。让它一个人 - 这必须是实现dispose / finalize模式的最简单方法。