开发者

Is IDisposable.Dispose() called automatically? [duplicate]

This question already has answers here: Closed 11 years ago.

Possible Duplicate:

Will the Garbage Collector call IDisposable.Dispose for me?

I have a Class which has s开发者_StackOverflowome unmanaged resources. My class implements the IDisposable interface and releases the unmanaged resources in the Dispose() method. Do I have to call the Dispose() method or will it be automatically called somehow? Will the Garbage Collector call it?


Dispose() will not be called automatically. If there is a finalizer it will be called automatically. Implementing IDisposable provides a way for users of your class to release resources early, instead of waiting for the garbage collector.

The preferable way for a client is to use the using statement which handles automatic calling of Dispose() even if there are exceptions.

A proper implementation of IDisposable is:

class MyClass : IDisposable
{
  private bool disposed = false;

  void Dispose() 
  { 
    Dispose(true); 
    GC.SuppressFinalize(this);
  }

  protected virtual void Dispose(bool disposing)
  {
    if(!disposed)
    {
      if(disposing)
      {
        // Manual release of managed resources.
      }
      // Release unmanaged resources.
      disposed = true;
    }
  }

  ~MyClass() { Dispose(false); }
}

If the user of the class calls Dispose() the cleanup takes place directly. If the object is catched by the garbage collector, it calls Dispose(false) to do the cleanup. Please note that when called from the finalizer (the ~MyClass method) managed references may be invalid, so only unmanaged resources can be released.


If you instantiate your object in a using statement, Dispose() is called for you when code exits the using block

using(var myObject = new MyDisposableObject())
{
  blah();
} // Dispose() is called here (or whenever the code exits the block)

If you don't use using, then it's up to you (the calling code) to dispose of your object by explicitely calling Dispose().

Also, you (the implementor of MyObject) can add support for a finalizer in case your caller doesn't call Dispose(). More info here.


You will have to call this method manually, maybe (assuming that "MyClass" implements "IDisposable") in a construct like

using(var myclass = new MyClass())
{
   // do something with myclass
}

// now 'myclass'is Disposed

In C# 8.0, you can write as below statement:

using var myclass=new MyClass();

and the "myclass" will be disposed automatically at the end of the scope.

The advantage of the using statement (compared to calling Dispose() explicitly) is that Dispose() is called no matter how you exit this block: by running past the end, encountering a return statement or having an exception thrown.


To make sure the resources are correctly disposed, you need to both implement IDisposable and call Dispose in the destructor(finalizer).

class Foo : IDisposable
{
    private bool m_disposed = false;

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

    ~Foo()
    {
        Dispose(false);
    }

    protected void Dispose(bool disposing)
    {
        if (!m_disposed)
        {
            if (disposing)
            { 
                //release managed resources
            }
            //release unmanaged resources

            m_disposed = true;
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜