成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C#.Net中的非托管代碼清理

開發 后端
本文就實現IDispose遇到的兩個問題做了一些分析,并提出了解決方案。最終方案同時實現了Finalize終結器和Dispose方式。

這兩天幫助其它項目組Review代碼,發現有些地方實現了IDispose接口,同時也發現了一些關于IDispose的問題:

1.A類型實現了IDispose接口,B類型里面含有A類型的字段,B類型沒有實現IDispose接口

2.一個類里面實現了Finalize終結器,同時也實現了IDispose接口,但在Dispose方法里面沒有調用GC.SuppressFinalize(this)方法.

下面我對以上兩個問題分別分析一下,并提出解決方案。

問題1

如果A類型里面有非托管資源需要在實現的IDispose接口里面釋放,由于B類型沒有實現IDispose接口,B類型的使用者要想釋放A類型的非托管資源并不方便.這樣的話,就有可能忘記了釋放A類型的非托管資源.

解決方案:

實現B類型的IDispose接口,在Dispose方法里面調用A類型的Dispose方法.這樣,B類型的使用者在調用B類型Dispose的同時,就把A類型的Dispose也調用了.

問題2

在Dispose方法里面沒有調用GC.SuppressFinalize(this)方法,會有什么問題呢,這樣會導致垃圾回收器不能對 這個類型的對象及時回收. 當GC開始工作的時候,它首先將沒有終結器的垃圾對象從內存中移除,有終結器的所有對象則添加到一個垃圾隊列當中。GC會調用一個新線程來執行這些對象的 終結器。當終結器執行完畢后,這個對象會從隊列中被移除。這個對象在隊列中移除之后,當GC再次開始工作的時候,這個對象才能夠被回收,所以有終結器的對 象會比沒有的在內存中保留更長的時間。在后面我會對這里再詳細的描述一下.

解決方案:

在Dispose方法中調用GC.SuppressFinalize(this)方法.這樣的話,就不會把有終結器的對象則添加到垃圾隊列當中.

切入正題

.net中,非托管代碼清理有兩種方式:Finalize方式和Dispose方式.

Finalize方式:通過對自定義類型實現一個Finalize方法來釋放非通過資源.

從.net2.0開始,C#編譯器不能對Finalize進行顯示的調用和重寫,必須使用析構函數來實現它.

class A
{
~A()
{
釋放資源;
}
}

上面的代碼就是通過Finalize方式來釋放資源的跟C++用析構函數釋放資源的代碼很象.

但是它實現方式和C++不同,因為它是由垃圾回收器來管理內存的.

大家看到了,用Finalize方式釋放非托管資源很簡單,但是如果你了解了他的實現方式,你可能就不會選擇用它來釋放非托管資源.

那Finalize方式在.net內部是如何實現的呢?

當GC(垃圾回收器)開始工作的時候,它首先將沒有終結器的垃圾對象從內存中移除,有終結器的所有對象則添加到一個終止化隊列當中。GC會調用一個 新線程來執行這些對象的終結器。當終結器執行完畢后,這些對象會從隊列中被移除。這時候由于這些對象在第一次檢測到的時候沒有被釋放,它們將會進入第1代 對象,直到GC檢測到第0代對象和第1代對象再次充滿時,這時候GC才會把剛才那些對象釋放掉,所以有終結器的對象會比沒有的在內存中保留更長的時間。

提示:垃圾回收器把托管堆中的對象分為3代,分別是0,1,2.一般分配為:0代約256K,1代約是2MB,第2代約是MB,代齡越高,容量就越 大,顯然效率也就越低.首先被添加到托管堆中的對象被定為第0代,當第0代充滿時,就會執行垃圾回收,未被回收的對象代領將提升1代.

由于以上原因應該避免僅使用Finalize方式釋放非托管資源.

Dispose模式:在自定義類中實現IDispose接口,在接口中的Dispose方法中對非托管資源進行釋放.閑話少說,上代碼

public class MyResourceRelease: IDisposable
{
/// 保證資源只用釋放一次
private bool _alreadyDisposed = false;
/// 用來判斷釋放資源的類別(托管和非托管)
protected virtual void Dispose(bool isDisposing)
{
if(_alreadyDisposed)
{
return;
}
if(isDisposing)
{
//釋放托管資源
}
//釋放非托管資源
_alreadyDisposed = true;
}
public void Dispose()
{
Dispose(true);
}
}

上面的代碼就是用Dispose方式釋放資源的方法.因為上面自定義的Dispose(bool isDisposing)方法是virtual的,所以還可以在派生類里面對它進行override

public class MyDerivedResource: MyResourceRelease
{
private bool _disposed = false;
protected override void Dispose(bool isDisposing)
{
if(_disposed)
{
return;
}
try
{
if(isDisposing)
{
//釋放托管資源
}
//釋放非托管資源
_disposed = true;
}
finally
{
base.Dispose(isDisposing);
}
}
}


這樣可以確保釋放繼承鏈上所有對象的引用資源,在整個繼承層次中傳播Dispose模式.

#p#

那用Dispose方式非托管資源就是最好的方法了嗎?

其實不然,因為類型實現了IDispose接口,這個類的使用者必須顯示調用Dispose方法,或者在創建該類型對象的時候使用using關鍵 字,對于一些粗心的使用者可能會忘記調用Dispose方法,或者沒有使用using關鍵字,這樣就導致了非托管資源沒有釋放的后果.

最佳方案

同時實現終結器和Dispose方式.這樣對于細心的使用者直接顯示調用Dispose方法會提高垃圾回收的性能,對于粗心的使用者雖然忘記了調用Dispose方法,但也不至于使得非托管資源得不到釋放.

注意這里用到了GC. SuppressFinalize(this)方法.

代碼如下:

public class MyResourceRelease: IDisposable
{
~MyResourceRelease()
{
Dispose(false);
}
/// 保證資源只用釋放一次
private bool _alreadyDisposed = false;
/// 用來判斷釋放資源的類別(托管和非托管)
protected virtual void Dispose(bool isDisposing)
{
if(_alreadyDisposed)
{
return;
}
if(isDisposing)
{
//釋放托管資源
}
//釋放非托管資源
_alreadyDisposed = true;
}
public void Dispose()
{
Dispose(true);
//阻止GC把該對象放入終結器隊列
GC.SuppressFinalize(this);
}
}

【編輯推薦】

  1. 淺談C#中的接口問題
  2. 淺談C# 4.0中的動態類型和動態編程
  3. C#連接數據庫特殊方法兩則
責任編輯:yangsai 來源: ITPUB論壇
相關推薦

2013-08-19 17:25:18

.Net托管

2011-06-17 15:55:19

ArrayListC#

2009-08-25 13:53:20

C#.NET rege

2009-08-26 14:23:14

C#.Net Fram

2010-01-25 15:55:50

托管C++

2009-09-01 16:14:05

ArrayList與A

2009-08-13 10:35:55

C#.NET操作XML

2009-08-24 16:19:54

C#.NET綁定Off

2009-08-26 10:09:22

C#編碼規范

2010-01-06 19:22:43

.NET Framew

2009-09-11 11:30:53

Net60C#.NET

2009-08-24 16:30:43

C#.NET綁定Off

2009-08-19 15:44:09

ObjectARX .

2023-07-07 13:56:54

2024-06-11 07:34:58

C#字符串性能

2023-07-17 11:25:35

.NET程序WinDbgPerfview

2009-07-30 14:14:07

非托管COM組件

2009-08-31 14:45:15

C#.NET多線程應用

2021-12-14 07:40:07

C# 異步流結合體

2009-08-19 16:19:33

Employee對象
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 九九热这里只有精品在线观看 | 欧美日韩综合精品 | 欧美日产国产成人免费图片 | 伊人91在线 | 免费一区二区三区在线视频 | 九九久久精品 | 美国一级黄色片 | 日日夜夜天天干 | 婷婷在线视频 | 国产精品一区二区三区在线 | 天天综合91 | 99亚洲精品| 精品一区二区三区日本 | 国产成人a亚洲精品 | 亚洲成人精品免费 | 久久九九网站 | 中文字幕91av | www.欧美视频| 一区天堂 | 福利视频网址 | 国产欧美视频一区二区 | 日韩国产欧美视频 | 在线91 | 国产成人久久精品一区二区三区 | 91精品国产综合久久婷婷香蕉 | 欧美久久综合 | 精品国产亚洲一区二区三区大结局 | 欧美在线一区二区三区 | 欧美一区二区三区在线播放 | 日本不卡一区二区三区 | 中文字字幕一区二区三区四区五区 | 中文字幕黄色大片 | 日本一区二区电影 | 欧美日韩综合精品 | 久久噜噜噜精品国产亚洲综合 | 在线精品一区二区三区 | 久久精品a级毛片 | 国产一级视频在线播放 | 精品国产18久久久久久二百 | 日韩一区二区黄色片 | 91精品久久久久 |