C#如何釋放未託管資源

來源:互聯網
上載者:User

在C#裡面有2種機制來釋放未託管資源:

  • 聲明一個解構函式(或終結器),作為類的一個成員
  • 在類中執行System.IDisposable介面

解構函式

下面這段代碼是一段帶有解構函式的簡單代碼:

using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace MemRelease{    class Program    {        ~Program()        {            // Orders.        }         static void Main(string[] args)        {        }    }} 

在IL DASM中,你會發現並沒有這個析構的方法。C#編譯器在編譯解構函式時,會隱式地把解構函式的代碼編譯為Finalize()方法的對應代碼,確保執行父類的Finalize()方法 看下這段代碼中對於解構函式的編譯:

.method family hidebysig virtual instance void         Finalize() cil managed{  // Code size       14 (0xe)  .maxstack  1  .try  {    IL_0000:  nop    IL_0001:  nop    IL_0002:  leave.s    IL_000c  }  // end .try  finally  {    IL_0004:  ldarg.0    IL_0005:  call       instance void [mscorlib]System.Object::Finalize()    IL_000a:  nop    IL_000b:  endfinally  }  // end handler  IL_000c:  nop  IL_000d:  ret} // end of method Program::Finalize 

 

是一個try…finally的結構,

try{// destructor implementation}finally{base.Finalize();}

~Program()解構函式中執行的代碼封裝在Finalize()方法的一個try塊中。對父類Finalize()方法的調用放在finally塊中,確保該調用的執行。

 

使用解構函式來釋放資源有幾個問題:

  1. 與C++解構函式相比,C#解構函式的問題是他們的不確定性。在刪除C++對象時,其解構函式會立即執行,但是由於垃圾收集器的工作方式,無法確定C#對象的解構函式何時執行。
  2. C#解構函式的執行會延遲物件最終從記憶體中刪除的時間。有解構函式的對象需要2次處理才能刪除:第一次調用解構函式時,沒有刪除對象,第二次調用才真正刪除對象。

IDisposable介面

在C#中,推薦使用System.IDisposable介面替代解構函式。IDisposable介面定義一個模式,為釋放未託管的資源提供了確定的機制,並避免產生解構函式固有的與垃圾函數器相關的問題。

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MemRelease{    class Program : IDisposable    {        public void Dispose()        {            // implementation        }                static void Main(string[] args)        {        }    }}

假定有一個類ResourceGobbler,它使用某些外部資源,且執行IDisposable介面。如果要執行個體化著各類的執行個體,使用它,然後釋放它,就可以使用下面的代碼。

ResourceGobbler theInstance = new ResoucrGobbler();// do your processingtheInstance.Dispose();

如果加入異常處理:

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MemRelease{    public class ResourceGobbler : IDisposable    {        public void Dispose()        {            //implementation        }    }    class Program     {                static void Main(string[] args)        {            ResourceGobbler theInstance = null;            try            {                theInstance = new ResourceGobbler();                // do your processing            }            finally            {                if (theInstance != null)                {                    theInstance.Dispose();                }             }        }    }}

即使在處理過程中出現異常,這個版本也可以確保總是在theInstance上調用Dispose(),總能釋放有theInstance使用的資源。

 

C#提供了一種文法,可以確保執行IDisposal介面的對象的引用超出範圍時,在該對象上自動調用Dispose().

using (ResourceGobbler theInstance =  new ResourceGobbler());{    // do your processing}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.