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

Pad*_*eep 54 .net c# idisposable

可能重复:
垃圾收集器是否会为我调用IDisposable.Dispose?

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

And*_*bel 64

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); }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 听起来您好像在说,如果 Finalizer 存在,则会自动调用 Dispose(即使 Finalizer 不调用 Dispose 方法)。但是显式 Finalizer 不会自动调用 Dispose 来执行此操作,除非您显式编写 Finalizer 代码来调用 Dispose。 (2认同)

Ser*_*ier 8

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

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

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

此外,您(MyObject的实现者)可以添加对终结器的支持,以防您的调用者不调用Dispose().更多信息在这里.


Han*_*ing 7

不得不手动调用此方法,也许(假设“MyClass”实现“IDisposable”)在类似的构造中

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

// now 'myclass'is Disposed
Run Code Online (Sandbox Code Playgroud)

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

using var myclass=new MyClass();
Run Code Online (Sandbox Code Playgroud)

并且“myclass”将在范围结束时自动处理。

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


Che*_*hen 7

要确保正确处理资源,您需要在析构函数(终结器)中实现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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @KyleDelaney几年前我曾经用'm_`作为私人成员的前缀...现在我正在使用`_`前缀.`m`代表`member`. (3认同)