簡體   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