logo
Published on developer.* Blogs (http://www.developerdotstar.com/community)

To Dispose or Not to Dispose ?

By Bijesh Karuvar
Created 2005-08-19 06:05

From http://weblogs.asp.net/jarnold/archive/2004/08/10/211969.aspx [1]

Myth:

Dispose() releases an object's memory.

Rationale:

Well, it's called 'Dispose' isn't it?

Truth:

Dispose() is merely a convenient place for a class developer to place any resource clean-up code, in the hope that clients will call it. Dispose does not free the managed memory allocated for an object. The only thing that can do that is the garbage collector; there is no way to deterministically (or manually) release memory.

Now, why should we call Dispose() for datasets and datatables and other disposable objects ?

Let's see an example:

Dim dsSomeData as Dataset
dsSomeData = objSomeObject.GetSomeData()
dsSomeData.Dispose()
dgDataGrid.DataSource = dsSomeData
dgDataGrid.DataBind()

If the Dispose() actually releases memory and marks it for disposing in the next garbage collection, this should throw an exception. But, guess what? The above code runs fine.

So, what does Dispose() for dataset and datatable actually do? Nothing! You can call the Dispose() method for the dataset, and the dataset still contains the dataset. No release of memory.

The Dispose method in DataSet exists ONLY because of side effect of inheritance-- in other words, it doesn't actually do anything useful in the finalization. The class DataSet inherits from "System.ComponentModel.MarshalByValueCompenent" which implements the IDisposable interface because it is a component. That being the case, it is only used to be treated as a component that you can put on a form. The method is not overridden in the System.Data.Dataset class and as such, it all depends what MarshalByValueCompenent does. Calling Dispose is just going to remove the DataSet from any component site that it's been added to.

This is the disassembled code of MarshalByValueComponent

Public Sub Dispose()
Me.Dispose(True)
GC.SuppressFinalize(Me)
End Sub

And the internal Me.Dispose(True) does this:

Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If disposing Then
SyncLock Me
If ((Not Me.site Is Nothing) AndAlso (Not Me.site.Container Is Nothing)) Then
Me.site.Container.Remove(Me)
End If
If (Not Me.events Is Nothing) Then
Dim handler1 As EventHandler = _
CType(Me.events.Item(MarshalByValueComponent.EventDisposed), EventHandler)
If (handler1 Is Nothing) Then
Return
End If
handler1.Invoke(Me, EventArgs.Empty)
End If
End SyncLock
End If
End Sub

Since the DataSet does not have a container, the above code practically doesn't do anything other than telling GC not to call Finalize method. If I understand this correctly, we'll never have to call dispose method on DataSets and DataTables.


Source URL:
http://www.developerdotstar.com/community/community/node/247