是否自动调用IDisposable.Dispose()

本文关键字:Dispose IDisposable 调用 是否 | 更新日期: 2023-09-27 18:04:36

可能重复:
垃圾回收器会为我调用IDisposable.Dispose吗?

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

是否自动调用IDisposable.Dispose()

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方法(调用时,托管引用可能无效,因此只能释放非托管资源。

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

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

如果不使用using,则由您(调用代码(通过显式调用dispose((来处理对象。

此外,您(MyObject的实现者(可以添加对终结器的支持,以防调用者没有调用Dispose((。点击此处了解更多信息。

您将必须手动调用此方法,可能(假设"MyClass"实现了"IDisposable"(在类似的构造中

using(var myclass = new MyClass())
{
   // do something with myclass
}
// now 'myclass'is Disposed

C#8.0中,您可以编写以下语句:

using var myclass=new MyClass();

并且"myclass"将在作用域的末尾自动处理。

using语句的优点(与显式调用Dispose((相比(是,无论您如何退出此块,都会调用Dispose():通过运行到末尾、遇到return语句或引发异常。

要确保资源得到正确部署,需要在析构函数(终结器(中实现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;
        }
    }
}