I have the following code:
public void Dispose() { if (_instance != null) { _instance = null; // Call GC.SupressFinalize to take this object off the finalization // queue and prevent finalization code for this object from // executing a second time. GC.SuppressFinalize(this); } }
Although there is a comment that explains purpose of that GC-related call, I still don't understand why it's there.
Isn't object destined for garbage collection once all instances cease from existence, like, when used in using
block?
What's the use case scenario where this would play important role?
Finalize method, is used to release unmanaged resources before an object is garbage-collected. If obj does not have a finalizer or the GC has already signaled the finalizer thread to run the finalizer, the call to the SuppressFinalize method has no effect.
Dispose should call GC. SuppressFinalize so the garbage collector doesn't call the finalizer of the object. To prevent derived types with finalizers from having to reimplement IDisposable and to call it, unsealed types without finalizers should still call GC. SuppressFinalize.
Dispose improves performance and optimizes memory by releasing unmanageable objects and scarce resources, like Graphics Device Interface (GDI) handles used in applications with restricted Windows space. The Dispose method, provided by the IDisposable interface, implements Dispose calls.
The GC does not call Dispose , it calls your finalizer (which you should make call Dispose(false) ).
When implementing the dispose pattern you might also add a finalizer to your class that calls Dispose()
. This is to make sure that Dispose()
always gets called, even if a client forgets to call it.
To prevent the dispose method from running twice (in case the object already has been disposed) you add GC.SuppressFinalize(this);
. The documentation provides a sample:
class MyResource : IDisposable { [...] // This destructor will run only if the Dispose method // does not get called. ~MyResource() { // Do not re-create Dispose clean-up code here. // Calling Dispose(false) is optimal in terms of // readability and maintainability. Dispose(false); } // Implement IDisposable. // Do not make this method virtual. // A derived class should not be able to override this method. public void Dispose() { Dispose(true); // This object will be cleaned up by the Dispose method. // Therefore, you should call GC.SupressFinalize to // take this object off the finalization queue // and prevent finalization code for this object // from executing a second time. GC.SuppressFinalize(this); } private void Dispose(bool disposing) { // Check to see if Dispose has already been called. if(!this.disposed) { // If disposing equals true, dispose all managed // and unmanaged resources. if(disposing) { // Dispose managed resources. component.Dispose(); } // Call the appropriate methods to clean up // unmanaged resources here. resource.Cleanup() } disposed = true; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With