Tuesday 29 May 2012

Some Notes about Finaliser and Dispose() Method in .NET


- A finaliser cannot be called explicitly therefore we cannot determine when exactly it will run. The finalisation process (using a queueing method called f-reachable queue) manages when objects' finalisers will be called. This finalisation process happens right before garbage collection.

- A finaliser does not accept any parameter and cannot be overloaded. They also do not support access modifiers.

- Finalisers should only be implemented on objects that use expensive resources. They are used to free up expensive resources that garbage collector does not know about. Therefore finalisers delay garbage collection.

- By using IDisposable and implementing its one and only Dispose() method, we are able to free up resources whenever we want by putting the codes in the Dispose() method. When combining this with using statement, we automatically have implemented an implicit try/finally block that will call the Dispose() method in the finally block.

- Object with finaliser should also implement IDisposable.

- Finaliser and Dispose() should have the same codes.

- Avoid any unhandled exception from happening inside a finaliser because this will be very hard to diagnose as finalisers run in their own thread.

- Dispose() should call System.GC.SuppressFinalize() which will remove the object from finalisation queue so that it can go to garbage collection immediately. Remember that finalisation must happen first before garbage collection. By calling System.GC.SuppressFinalize(), the resources clean up will not be repeated twice.

- The codes inside Dispose() or finaliser should be simple and do not refer to other objects. The codes should only be there for freeing up resources.

- If an object's class has a base class that implements Dispose() method then the derived class implementation should call the base class' Dispose().

- Dispose() method should be safe to be called multiple times.

- An object should be marked as unusable after its Dispose() method is called. An ObjectDisposedException() should be thrown when the object is tried to be used again.


Reference:
Essential C# 4.0 - Mark Michaelis , p 393-400

No comments: