Finalize vs Dispose
Solution 1:
The finalizer method is called when your object is garbage collected and you have no guarantee when this will happen (you can force it, but it will hurt performance).
The Dispose
method on the other hand is meant to be called by the code that created your class so that you can clean up and release any resources you have acquired (unmanaged data, database connections, file handles, etc) the moment the code is done with your object.
The standard practice is to implement IDisposable
and Dispose
so that you can use your object in a using
statment. Such as using(var foo = new MyObject()) { }
. And in your finalizer, you call Dispose
, just in case the calling code forgot to dispose of you.
Solution 2:
Others have already covered the difference between Dispose
and Finalize
(btw the Finalize
method is still called a destructor in the language specification), so I'll just add a little about the scenarios where the Finalize
method comes in handy.
Some types encapsulate disposable resources in a manner where it is easy to use and dispose of them in a single action. The general usage is often like this: open, read or write, close (Dispose). It fits very well with the using
construct.
Others are a bit more difficult. WaitEventHandles
for instances are not used like this as they are used to signal from one thread to another. The question then becomes who should call Dispose
on these? As a safeguard types like these implement a Finalize
method, which makes sure resources are disposed when the instance is no longer referenced by the application.
Solution 3:
Finalize is the backstop method, called by the garbage collector when it reclaims an object. Dispose is the "deterministic cleanup" method, called by applications to release valuable native resources (window handles, database connections, etc.) when they are no longer needed, rather than leaving them held indefinitely until the GC gets round to the object.
As the user of an object, you always use Dispose. Finalize is for the GC.
As the implementer of a class, if you hold managed resources that ought to be disposed, you implement Dispose. If you hold native resources, you implement both Dispose and Finalize, and both call a common method that releases the native resources. These idioms are typically combined through a private Dispose(bool disposing) method, which Dispose calls with true, and Finalize calls with false. This method always frees native resources, then checks the disposing parameter, and if it is true it disposes managed resources and calls GC.SuppressFinalize.
Solution 4:
Finalize gets called by the GC when this object is no longer in use.
Dispose is just a normal method which the user of this class can call to release any resources.
If user forgot to call Dispose and if the class have Finalize implemented then GC will make sure it gets called.
Solution 5:
Finalize
- Finalizers should always be
protected
, notpublic
orprivate
so that the method cannot be called from the application's code directly and at the same time, it can make a call to thebase.Finalize
method - Finalizers should release unmanaged resources only.
- The framework does not guarantee that a finalizer will execute at all on any given instance.
- Never allocate memory in finalizers or call virtual methods from finalizers.
- Avoid synchronization and raising unhandled exceptions in the finalizers.
- The execution order of finalizers is non-deterministic—in other words, you can't rely on another object still being available within your finalizer.
- Do not define finalizers on value types.
- Don't create empty destructors. In other words, you should never explicitly define a destructor unless your class needs to clean up unmanaged resources and if you do define one, it should do some work. If, later, you no longer need to clean up unmanaged resources in the destructor, remove it altogether.
Dispose
- Implement
IDisposable
on every type that has a finalizer - Ensure that an object is made unusable after making a call to the
Dispose
method. In other words, avoid using an object after theDispose
method has been called on it. - Call
Dispose
on allIDisposable
types once you are done with them - Allow
Dispose
to be called multiple times without raising errors. - Suppress later calls to the finalizer from within the
Dispose
method using theGC.SuppressFinalize
method - Avoid creating disposable value types
- Avoid throwing exceptions from within
Dispose
methods
Dispose/Finalized Pattern
- Microsoft recommends that you implement both
Dispose
andFinalize
when working with unmanaged resources. TheFinalize
implementation would run and the resources would still be released when the object is garbage collected even if a developer neglected to call theDispose
method explicitly. - Cleanup the unmanaged resources in the
Finalize
method as well asDispose
method. Additionally call theDispose
method for any .NET objects that you have as components inside that class(having unmanaged resources as their member) from theDispose
method.