釋放未托管的資源有兩種方法
1、析構(gòu)函數(shù)
2、實(shí)現(xiàn)System.IDisposable接口
一、析構(gòu)函數(shù)
構(gòu)造函數(shù)可以指定必須在創(chuàng)建類的實(shí)例時(shí)進(jìn)行的某些操作,在垃圾收集器刪除對(duì)象時(shí),也可以調(diào)用析構(gòu)函數(shù)。析構(gòu)函數(shù)初看起來(lái)似乎是放置釋放未托管資源、執(zhí)行一般清理操作的代碼的最佳地方。但是,事情并不是如此簡(jiǎn)單。由于垃圾回收器的運(yùn)行規(guī)則決定了,不能在析構(gòu)函數(shù)中放置需要在某一時(shí)刻運(yùn)行的代碼,如果對(duì)象占用了寶貴而重要的資源,應(yīng)盡可能快地釋放這些資源,此時(shí)就不能等待垃圾收集器來(lái)釋放了.
實(shí)例
C# 代碼 復(fù)制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中,你會(huì)發(fā)現(xiàn)并沒有這個(gè)析構(gòu)的方法。C#編譯器在編譯析構(gòu)函數(shù)時(shí),會(huì)隱式地把析構(gòu)函數(shù)的代碼編譯為Finalize()方法的對(duì)應(yīng)代碼,確保執(zhí)行父類的Finalize()方法 看下這段代碼中對(duì)于析構(gòu)函數(shù)的編譯:
C# 代碼 復(fù)制.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
使用析構(gòu)函數(shù)來(lái)釋放資源有幾個(gè)問(wèn)題:
1、與C++析構(gòu)函數(shù)相比,C#析構(gòu)函數(shù)的問(wèn)題是他們的不確定性。在刪除C++對(duì)象時(shí),其析構(gòu)函數(shù)會(huì)立即執(zhí)行,但是由于垃圾收集器的工作方式,無(wú)法確定C#對(duì)象的析構(gòu)函數(shù)何時(shí)執(zhí)行。
2、C#析構(gòu)函數(shù)的執(zhí)行會(huì)延遲對(duì)象最終從內(nèi)存中刪除的時(shí)間。有析構(gòu)函數(shù)的對(duì)象需要2次處理才能刪除:第一次調(diào)用析構(gòu)函數(shù)時(shí),沒有刪除對(duì)象,第二次調(diào)用才真正刪除對(duì)象。
二、IDisposable接口
IDisposable接口定義了一個(gè)模式,為釋放未托管的資源提供了確定的機(jī)制,并避免產(chǎn)生析構(gòu)函數(shù)固有的與垃圾函數(shù)器相關(guān)的問(wèn)題。IDisposable接口聲明了一個(gè)方法Dispose(),它不帶參數(shù),返回void。
1、MSDN建議按照下面的模式實(shí)現(xiàn)IDisposable接口
C# 代碼 復(fù)制public class Foo: IDisposable
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注