Finalizer and IDisposable
Based on the documentation (MSDN: link), it is clear that one should use the IDisposable pattern when implementing a finalizer.
But do you need to implement a finalizer if you implement IDisposable (so as to provide a deterministic way of disposing the object), and you dont have any unmanaged resources to clean up?
As I see it, if the class has only managed resources and if you dont call Dispose, the managed resources will automatically get cleaned up by the GC and hence no need to implement the finalizer. Am I wrong?
Also, what if I am using my Dispose method to clean up event handlers. As Dispose wont automatically get called by the GC, should I implement a Finalizer, to ensure that eventhandlers get unwired?
No, you do not need to implement a finalizer if you have a class that implements IDisposable (that is if you have implemented the pattern correctly, and that you only have managed resources to dispose of).
(If you do, it can actually affect the lifetime of your object, as objects with finalizers get added to the finalization queue in the GC and can live longer than they need to - this can be a problem if your objects are large.)
You should not add a finalizer unless you have unmanaged resources.
A class that owns managed disposable resources but not unmanaged resources should implement the full Dispose
pattern, but not have a finalizer.
If the class is not sealed
, it should call GC.SuppressFinalize(this)
in its Dispose()
method in case an inherited class adds a finalizer.
No, you are correct, if your object holds an object that holds an unmanaged resource then you should implement IDisposable so that you can call its Dispose on your Dispose, but you don't need a finaliser as its finaliser will deal with that matter.
Indeed, trying to do anything with a finalisable member from in a finaliser is fraught, as which order the finalisers will run is not deterministic, so you can get some nasty bugs if you try to do this.
As a rule it's much better to have a class either hold 1 or 0 unmanaged resources. And if it has 1 unmanaged resource, it should have as little other state as needed to deal with it (ie no other disposable members). SafeHandle is a good way of dealing with this. If a class needs to deal with several unmanaged resources it should do so by handling said resources through these handler classes. Then a finaliser & IDisposable becomes easy; either you have the sole unmanaged resource to deal with in both (suppress the finaliser if dispose is called) or you only need IDisposable.
Because having to deal with unmanaged resources directly is relatively rare, the chances are you will never have to write a finaliser (I think I have done so once, in real code). Because sensible people don't do much else in classes that handle unmanaged resources, the whole Dispose(bool) thing is unnecessary too.
链接地址: http://www.djcxy.com/p/54490.html