Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the purpose of GC.SuppressFinalize(this) in Dispose() method?

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?

like image 850
mr.b Avatar asked Jun 14 '10 15:06

mr.b


People also ask

What is the use of GC SuppressFinalize?

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.

Why do we need to call GC SuppressFinalize?

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.

What does the Dispose method do?

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.

Does GC Call Dispose?

The GC does not call Dispose , it calls your finalizer (which you should make call Dispose(false) ).


1 Answers

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;              } } 
like image 152
Dirk Vollmar Avatar answered Sep 20 '22 18:09

Dirk Vollmar