IDisposable.Dispose()是否自动调用?

时间:2011-08-06 13:29:21

标签: c# .net idisposable

  

可能重复:
  Will the Garbage Collector call IDisposable.Dispose for me?

我有一个具有一些非托管资源的类。我的类实现了IDisposable接口,并在Dispose()方法中释放了非托管资源。我是否必须调用Dispose()方法或以某种方式自动调用?垃圾收集器会调用它吗?

4 个答案:

答案 0 :(得分:61)

Dispose()不会自动调用。如果有终结器,它将自动调用。实现IDisposable为类的用户提供了一种提前释放资源的方法,而不是等待垃圾收集器。

客户端的首选方法是使用using语句来处理Dispose()的自动调用,即使存在例外情况。

IDisposable的正确实施是:

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); }
}

如果该类的用户调用Dispose(),则直接进行清理。如果垃圾收集器捕获了该对象,则会调用Dispose(false)进行清理。请注意,从终结器(~MyClass方法)调用时,托管引用可能无效,因此只能释放非托管资源。

答案 1 :(得分:6)

如果您在using语句中实例化对象,则在代码退出using块时为您调用Dispose()

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

如果您不使用using,则由您(调用代码)通过明确调用Dispose()来处理您的对象。

此外,您(MyObject的实现者)可以在调用者不调用Dispose()的情况下添加对终结器的支持。更多信息here

答案 2 :(得分:6)

为了确保正确处理资源,您需要在析构函数(终结器)中实现IDisposable并调用Dispose

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;
        }
    }
}

答案 3 :(得分:4)

手动调用此方法,可能在

之类的结构中
using(var myclass = new MyClass())
{
   // do something with myclass
}

// now 'myclass'is Disposed
相关问题