title: Is this IDisposable implementation correct?
body: <p>I can never remember all the rules for implementing the IDisposable interface, so I tried to come up with a base class that takes care of all of this and makes IDisposable easy to implement. I just wanted to hear your opinion if this implementation is ok as it is or whether you see something I could improve. The user of this base class is supposed to derive from it and then implement the two abstract methods <code>ReleaseManagedResources()</code> and <code>ReleaseUnmanagedResources()</code>. So here is the code:</p>
  
  <pre><code>public abstract class Disposable : IDisposable
  {
      private bool _isDisposed;
      private readonly object _disposeLock = new object();
  
      /// &lt;summary&gt;
      /// called by users of this class to free managed and unmanaged resources
      /// &lt;/summary&gt;
      public void Dispose() {
          DisposeManagedAndUnmanagedResources();
      }
  
      /// &lt;summary&gt;
      /// finalizer is called by garbage collector to free unmanaged resources
      /// &lt;/summary&gt;
      ~Disposable() { //finalizer of derived class will automatically call it's base finalizer
          DisposeUnmanagedResources();
      }
  
      private void DisposeManagedAndUnmanagedResources() {
          lock (_disposeLock) //make thread-safe
              if (!_isDisposed) { //make sure only called once
                  try { //suppress exceptions
                      ReleaseManagedResources();
                      ReleaseUnmanagedResources();
                  }
                  finally {
                      GC.SuppressFinalize(this); //remove from finalization queue since cleaup already done, so it's not necessary the garbage collector to call Finalize() anymore
                      _isDisposed = true;
                  }
              }
      }
  
      private void DisposeUnmanagedResources() {
          lock (_disposeLock) //make thread-safe since at least the finalizer runs in a different thread
              if (!_isDisposed) { //make sure only called once
                  try { //suppress exceptions
                      ReleaseUnmanagedResources();
                  }
                  finally {
                      _isDisposed = true;
                  }
              }
      }
  
      protected abstract void ReleaseManagedResources();
      protected abstract void ReleaseUnmanagedResources();
  
  }
  </code></pre>