4

See the code sample from MSDN: (http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=VS.100).aspx)

// Design pattern for a base class.
public class Base: IDisposable
{
  private bool disposed = false;

  //Implement IDisposable.
  public void Dispose()
  {
      Dispose(true);
      GC.SuppressFinalize(this);
  }

  protected virtual void Dispose(bool disposing)
  {
      if (!disposed)
      {
          if (disposing)
          {
              // Free other state (managed objects).
          }
          // Free your own state (unmanaged objects).
          // Set large fields to null.
          disposed = true;
      }
  }

  // Use C# destructor syntax for finalization code.
  ~Base()
  {
      // Simply call Dispose(false).
      Dispose (false);
  }
}

In the Dispose() implementation it calls GC.SupressFinalize();, but provide a destructor to finalise the object.

What is the point of providing an implementation for the destructor when GC.SuppressFinalize() is called?

Just little bit confused what the intentions are?

stuartd
  • 70,509
  • 14
  • 132
  • 163
msuhash
  • 266
  • 3
  • 12

2 Answers2

6

If someone forgets to call Dispose, the finalizer will (eventually) run to do final cleanup. Since finalization hurts performance, ideally no-one will forget to Dispose. The using construct helps a little with that.

Kate Gregory
  • 18,808
  • 8
  • 56
  • 85
  • 1
    its not finalization which hurts performance. It is the GC which is costly. Especially on gen2/LOH collections and this is where most disposable ressources are expected to/should lay. Clean up via finalization does not cost more than clean up via Dispose(). But it happens later and undeterministically. This is the reason, why Dispose should be called manually. – user492238 Jan 17 '11 at 09:35
  • 1
    @user492238 - When GC happens, and all the refs to you are gone, having a finalizer gets you put in the "oh I need to run the finalizers on this" list instead of cleaned up. And that hurts perf. You are right that actually finalizing isn't the point. It's having a finalizer that has not been run yet, because someone forgot to dispose. – Kate Gregory Jan 17 '11 at 12:39
6

There are 2 scenarios:

  • Your code calls Dispose (preferred) and the Finalizer is canceled, eliminating the overhead.
  • Your code 'leaks' the object and the GC calls the Finalizer.
H H
  • 263,252
  • 30
  • 330
  • 514
  • Thanks for this. Make sense when object is used without "using" context elsewhere in the system. – msuhash Nov 16 '10 at 11:56