|
原文地址:http://www./csharpspace/8927r1397.shtml MSDN建議按照下面的模式實(shí)現(xiàn)IDisposable接口:
1 public class Foo: IDisposable
2 {
3 public void Dispose()
4 {
5 Dispose(true);
6 GC.SuppressFinalize(this);
7 }
8
9 protected virtual void Dispose(bool disposing)
10 {
11 if (!m_disposed)
12 {
13 if (disposing)
14 {
15 // Release managed resources
16 }
17 // Release unmanaged resources
18 m_disposed = true;
19 }
20 }
21
22 ~Foo()
23 {
24 Dispose(false);
25 }
26 private bool m_disposed;
27 }
? 在.NET的對(duì)象中實(shí)際上有兩個(gè)用于釋放資源的函數(shù):Dispose和Finalize。Finalize的目的是用于釋放非托管的資源,而Dispose是用于釋放所有資源,包括托管的和非托管的。 在這個(gè)模式中,void Dispose(bool disposing)函數(shù)通過(guò)一個(gè)disposing參數(shù)來(lái)區(qū)別當(dāng)前是否是被Dispose()調(diào)用。如果是被Dispose()調(diào)用,那么需要同時(shí)釋放 托管和非托管的資源。如果是被~Foo()(也就是C#的Finalize())調(diào)用了,那么只需要釋放非托管的資源即可。 這是因?yàn)椋珼ispose()函數(shù)是被其它代碼顯式調(diào)用并要求釋放資源的,而Finalize是被GC調(diào)用的。在GC調(diào)用的時(shí)候Foo所引用的其它 托管對(duì)象可能還不需要被銷(xiāo)毀,并且即使要銷(xiāo)毀,也會(huì)由GC來(lái)調(diào)用。因此在Finalize中只需要釋放非托管資源即可。另外一方面,由于在 Dispose()中已經(jīng)釋放了托管和非托管的資源,因此在對(duì)象被GC回收時(shí)再次調(diào)用Finalize是沒(méi)有必要的,所以在Dispose()中調(diào)用 GC.SuppressFinalize(this)避免重復(fù)調(diào)用Finalize。 然而,即使重復(fù)調(diào)用Finalize和Dispose也是不存在問(wèn)題的,因?yàn)橛凶兞縨_disposed的存在,資源只會(huì)被釋放一次,多余的調(diào)用會(huì)被忽略過(guò)去。 因此,上面的模式保證了: 1、 Finalize只釋放非托管資源; 2、 Dispose釋放托管和非托管資源; 3、 重復(fù)調(diào)用Finalize和Dispose是沒(méi)有問(wèn)題的; 4、 Finalize和Dispose共享相同的資源釋放策略,因此他們之間也是沒(méi)有沖突的。 在C#中,這個(gè)模式需要顯式地實(shí)現(xiàn),其中C#的~Foo()函數(shù)代表了Finalize()。而在C /CLI中,這個(gè)模式是自動(dòng)實(shí)現(xiàn)的,C 的類(lèi)析構(gòu)函數(shù)則是不一樣的。 按照C 語(yǔ)義,析構(gòu)函數(shù)在超出作用域,或者delete的時(shí)候被調(diào)用。在Managed C (即.NET 1.1中的托管C )中,析構(gòu)函數(shù)相當(dāng)于CLR中的Finalize()方法,在垃圾收集的時(shí)候由GC調(diào)用,因此,調(diào)用的時(shí)機(jī)是不明確的。在.NET 2.0的C /CLI中,析構(gòu)函數(shù)的語(yǔ)義被修改為等價(jià)與Dispose()方法,這就隱含了兩件事情: 1、 所有的C /CLI中的CLR類(lèi)都實(shí)現(xiàn)了接口IDisposable,因此在C#中可以用using關(guān)鍵字來(lái)訪問(wèn)這個(gè)類(lèi)的實(shí)例。 2、 析構(gòu)函數(shù)不再等價(jià)于Finalize()了。 ? ----------------------------------以下是CSDN上一位高手的總結(jié)---------------------------------------------- 1、Finalize方法(C#中是析構(gòu)函數(shù),以下稱(chēng)析構(gòu)函數(shù))是用于釋放非托管資源的,而托管資源會(huì)由GC自動(dòng)回收。所以,我們也可以這樣來(lái)區(qū)分 托管和非托管資源。所有會(huì)由GC自動(dòng)回收的資源,就是托管的資源,而不能由GC自動(dòng)回收的資源,就是非托管資源。在我們的類(lèi)中直接使用非托管資源的情況很 少,所以基本上不用我們寫(xiě)析構(gòu)函數(shù)。? |
|
|
來(lái)自: 印度阿三17 > 《開(kāi)發(fā)》