Dispose Vs Finalize

What are unmanaged resources?

File handler, Database connection, socket connection are example of unmanaged resource.

.Net garbage collector is designed to handle managed code. We need to implement IDisposable interface when we are using unmanaged resource directly.

There are 2 ways to call dispose method:

  1. Using : If object is implementating IDisposable interface we can use Using keyword, which will call objects Dispose method.
  2. Try/Catch/Finally: We can call Dispose in finally.

IDisposable and the inheritance hierarchy
A base class with subclasses that should be disposable must implement IDisposable as follows.
You should use this pattern whenever you implement IDisposable on any type that isn’t sealed.

It should provide one public, non-virtual Dispose() method and a protected virtual Dispose(Boolean disposing) method.

The Dispose() method must call Dispose(true) and should suppress finalization for performance.

The base type should not include any finalizers.

To implement Dispose method for custom class, you need to implement IDisposable interface.
IDisposable interface expose Dispose method where code to release unmanaged resource will be written.

Finalize

Finalize method is called destructor of the class. Finalize method can not be called explicitly in the code. Only Garbage collector can call the the Finalize when object become inaccessible. Finalize method cannot be implemented directly it can only be implement via declaring destructor.

Rule

For a class owning managed resources, implement IDisposable (but not a finalizer).
For a class owning at least one unmanaged resource, implement both IDisposable and a finalizer.

To avoid code duplication, Dispose() and the finalizer should be implemented like this (in pseudo-code):

public void Dispose() {
Dipose(true);
GC.SuppressFinalize(this);
}

GC.SuppressFinalize() simply prevents the finalizer from being called. Since the finalizer’s only task is to free unmanaged data, it doesn’t need to be called if Dispose() was already called (and already freed all unmanaged data by calling the finalizer).
Using GC.SuppressFinalize() give a small performance improvement but nothing more.

The default dispose implementation pattern used in the previous sections create a method called Dispose(bool). This method is protected virtual and is meant to be overridden by child classes – in case they need to dispose some data of their own.

In C#, an implementation must:

first check whether it already has been disposed
then dispose everything
and then call the base method

The base method is called last to ensure that child classes are disposed before their parent classes.

Leave a Reply

Your email address will not be published. Required fields are marked *