繁体   English   中英

调用Dispose到底能做什么?

[英]What exactly does calling Dispose do?

我一直在尝试加深对垃圾收集,托管和非托管资源以及有关内存管理的“适当的设计原则”的理解,因为我有兴趣进入“较低级别”的编程以及这类性质的东西。

我了解您应该使用using块或其他解决方案来确保这些不受管理的资源确实得到处置,但是我不了解幕后情况。

我在看这篇文章:在MSDN上实现Dispose方法 ,并被这行特别困惑:

为了确保始终正确地清理资源,Dispose方法应可多次调用而不会引发异常。

让我们看一下它们为处理模式提供的示例代码:

class DerivedClass : BaseClass
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Instantiate a SafeHandle instance.
   SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);

   // Protected implementation of Dispose pattern.
   protected override void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) 
      {
         handle.Dispose();
         // Free any other managed objects here.
      }

      // Free any unmanaged objects here.

      disposed = true;

      // Call base class implementation.
      base.Dispose(disposing);
   }
}

相信上面引用的文字基本上是这样说的:“我们添加了一个bool disposed属性,以便我们可以检查是否为true然后return true 。如果为false那么我们将处理实际资源。这样我们就不会实际多次处置”

但这对我来说没有意义。 如果我们已经摆脱了一个对象,您如何第二次调用Dispose

为了进行调查,我编写了一个包含以下3行的控制台应用程序:

var cmd = new SqlCommand();
cmd.Dispose();
cmd.Dispose();

这可以毫无问题地进行编译和执行-考虑到文章中引用的文字,这很有意义。 但我不了解实际情况。

我设置一个断点,然后跨过每一行。 在调用第一个Dispose之后,我希望Visual Studio中的Locals窗口告诉我cmdnull 然后按照这种思路,我问自己:“你怎么称呼Dispose on null ?” 显然,你不能。 那到底是怎么回事? 为什么在第一次处置后, cmd仍然是SqlCommand对象?

在此处输入图片说明

Dispose 到底能做什么,并且如果我已经处置了对象,为什么它在所有意图和目的上似乎仍然存在?

为什么/以下内容如何编译和运行而不会出现问题?

var cmd = new SqlCommand();
cmd.Dispose();
cmd.CommandText = "I figured this would throw an exception but it doesn't";

IDisposable接口由多个使用类调用,并且-如Dark Falcon所述-当您将类的用法封装在using块中时。 这样可以更轻松地保持非托管资源的清洁。 但是Dispose就像其他任何方法一样,不要与析构函数/ finalizer混淆(这显然是您期望的)

Dispose没什么特别的,除了using语句可以为您调用它。 除此之外,它与任何其他.NET函数一样。 它不会神奇地将任何变量设置为null ,如果再次使用该对象或诸如此类,则会引发异常。

同样, IDisposable在任何方面都不是特殊的接口,只是using语句中的对象必须实现它。 您可以考虑using语句是这样的:

// using(var a = somethingDisposable()) {otherCode();}
var a = somethingDisposable();
try
{
    otherCode();
}
finally
{
    if(a != null)
        ((IDisposable)a).Dispose();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM