serhio
serhio

Reputation: 28586

Implement Dispose or Finalize?

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

Upvotes: 2

Views: 11885

Answers (4)

BlueMonkMN
BlueMonkMN

Reputation: 25601

The finalizer should call this class' Dispose passing false for the disposing parameter rather than directly disposing of objects this class owns. See MSDN.

Edit: So to answer the question, disposing of owned objects should be done in Dispose, not Finalize.

Edit 2: Notice, this means that if the object is finalized without being disposed, then Dispose will only get called (by Finalize) with the "false" parameter, and the child objects will not be disposed by this class. This is correct because they are managed objects and will be finalized when the framework feels like it if not explicitly disposed.

Upvotes: 3

Henk Holterman
Henk Holterman

Reputation: 273189

You should not (don't have to) Dispose managed resources from the Finalizer:

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

And from that it follows that if your class does not have unmanaged resources you don't need a Finalizer at all.

Note: Your class is missing the Public Sub Dispose() overload.

Edit:

Since foo and bar are managed resources (extending Component) you only need the Protected Overrides Sub Dispose(disposing As Boolean) method. The version in the question is correct. And simply drop the Finalize().

Upvotes: 4

MarkJ
MarkJ

Reputation: 30398

What are you inheriting from? I suspect it may be System.ComponentModel.Container, directly or indirectly.

In which case, you don't need to do anything. System.ComponentModel.Container automatically disposes of any components it contains, in its Dispose method. Let it alone - that has to be the easiest way to implement the dispose/finalise pattern.

Upvotes: 2

HadleyHope
HadleyHope

Reputation: 1173

Dispose is when you explicitly want to release some resources before the garbage collector frees the object.

Finalize is automatically called when or if the garbage collector gets around to freeing the object.

If you have many objects that hold on to resource's then since you should not be controlling garbage collection you should be using Dispose.

From the framework documentation:

Note that even when you provide explicit control by way of Dispose, you should provide implicit cleanup using the Finalize method. Finalize provides a backup to prevent resources from permanently leaking if the programmer fails to call Dispose.

Implementing Finalize and Dispose to Clean Up Unmanaged Resources

Upvotes: 1

Related Questions