Reputation: 3451
What about below disposable pattern?
using System;
public class MyClass : IDisposable
{
public void Dispose()
// Implement IDisposable
{
//just do the cleanup
GC.SuppressFinalize(this);
}
}
I meant to say, if there are no un-managed resources do I need finalizer? Isn't the above disposable pattern is good enough? Yes, even though users/developers doesn't invoke dispose, doesn't GC invoke dispose by default?
And what about the order in which GC invokes dispose and finalizers?
Please see this question for more details.
In other words, when we have finalizer, why do we call Dispose
with false as parameter?
From http://msdn.microsoft.com/en-us/magazine/cc163392.aspx#S2, looks like its always advisable to release unmanaged resources from finalizer and not the managed references.
It's always recommended to release unmanaged resources from Dispose method. I still didn't get the total gist when reading the article.
But if there are no unmanaged resources, the below pattern should work.
According to msdn.microsoft.com/en-us/magazine/cc163392.aspx#S2, msdn.microsoft.com/en-us/library/fs2xkftw.aspx it's recommended to release native resources in finalizer and all of them with dispose(). If dispose() is called explicitly, it can suppress finalizer i.e. if there no native resources, we don't need finalizer.
using System;
public class MyClass : IDisposable
{
private bool disposed = false;
protected virtual void Dispose(bool suppressFinalize)
{
if (!disposed)
{
//Just do the cleanup
//and release resources
disposed = true;
}
if (!suppressFinalize)
{
GC.SuppressFinalize(this);
}
}
public void Dispose()
// Implement IDisposable
{
Dispose(true);
}
~MyClass() // the finalizer
{
Dispose(false);
}
}
Upvotes: 4
Views: 2162
Reputation: 755259
Finalization + IDisposable
in .Net is really two distinct problems which are attempted to be solved with the single disposable pattern.
Unmanaged resources are items which aren't in the control of the CLR and garbage collector. Items like file handles, memory returned from PInvoke, etc ... If these resources aren't explicitly freed by user code they will leak and be around for the remainder of the process lifetime. It's critical that they are freed.
This is where the finalizer comes in. It will run on an object just before it is collected by the CLR. This doesn't require the consumer follow the disposable pattern and hence is a good fallback for ensuring unmanaged resources are freed to prevent a leak.
If your code doesn't contain any directly held unmanaged resources then there is no reason to have a finalizer. It is the responsibility of the code which holds the unmanaged resource to have the finalizer.
Upvotes: 4
Reputation: 1502716
Because you might have direct references to unmanaged resources (e.g. Windows handles) and you want to release them even if no-one calls Dispose
.
This is very rare though - usually you only really have indirect references to unmanaged resources, via other managed types which will have finalizers if they need them.
Upvotes: 15