亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

析構函數和Dispose的使用區別

2019-11-17 02:44:58
字體:
來源:轉載
供稿:網友

析構函數和Dispose的使用區別

老生常談的問題了,MSDN也有非常詳細的說明但看起來不是很系統。也曾經做過分析,但沒有總結下來又忘了,這次整理一下MSDN和網上搜集的一些資料,以備不時只需。

下面是MSDN對這兩個函數的建議使用方法

 1 MSDN建議 2     // Design pattern for a base class. 3     public class Base : IDisposable 4     { 5         //保證重復釋放資源時系統異常 6         PRivate bool _isDisposed = false; 7  8         // 析構函數,編譯器自動生成Finalize()函數由GC自動調用,保證資源被回收。 9         // 最好不要聲明空析構函數,造成性能問題10         // 如果沒有引用非托管資源就不需要顯示聲明析構函數,會造成性能問題,系統會自動生成默認析構函數11         ~Base()12         {13             // 此處只需要釋放非托管代碼即可,因為GC調用時該對象資源可能還不需要釋放14             Dispose(false);15         }16 17         //外部手動調用或者在using中自動調用,同時釋放托管資源和非托管資源18         public void Dispose()19         {20             Dispose(true);21             GC.SuppressFinalize(this); ///告訴GC不需要再次調用22         }23 24         protected virtual void Dispose(bool disposing)25         {26             if (!_isDisposed)27             {28                 if (disposing)29                 {30                     //釋放托管資源31                 }32                 // 釋放非托管資源33                 // 釋放大對象34 35                 this._isDisposed = true;36             }37            38         }39 40     }

下面是通過Reflector工具對上面代碼反射出來的結果,可以看出析構函數直接被翻譯成Finalize()函數了,因為Finalize函數不能被重寫,所以只能用析構函數的方式實現Finalize方法。

 1 Reflector反射結果 2 public class Base : IDisposable 3 { 4     // Fields 5     private bool _isDisposed; 6  7     // Methods 8     public Base(); 9     public void Dispose();10     protected virtual void Dispose(bool disposing);11     protected override void Finalize(); 12 }

在.NET的對象中實際上有兩個用于釋放資源的函數:Dispose和Finalize。Finalize的目的是用于釋放非托管的資源,而Dispose是用于釋放所有資源,包括托管的和非托管的。

在這個模式中,void Dispose(bool disposing)函數通過一個disposing參數來區別當前是否是被Dispose()調用。如果是被Dispose()調用,那么需要同時釋放 托管和非托管的資源。如果是被~Base()(也就是C#的Finalize())調用了,那么只需要釋放非托管的資源即可。

這是因為,Dispose()函數是被其它代碼顯式調用并要求釋放資源的,而Finalize是被GC調用的。在GC調用的時候Base所引用的其它托管對象可能還不需要被銷毀,并且即使要銷毀,也會由GC來調用。因此在Finalize中只需要釋放非托管資源即可。另外一方面,由于在 Dispose()中已經釋放了托管和非托管的資源,因此在對象被GC回收時再次調用Finalize是沒有必要的,所以在Dispose()中調用 GC.SuppressFinalize(this)避免重復調用Finalize。

然而,即使重復調用Finalize和Dispose也是不存在問題的,因為有變量_isDisposed的存在,資源只會被釋放一次,多余的調用會被忽略過去。因此,上面的模式保證了:

1、 Finalize只釋放非托管資源;

2、 Dispose釋放托管和非托管資源;

3、 重復調用Finalize和Dispose是沒有問題的;

4、 Finalize和Dispose共享相同的資源釋放策略,因此他們之間也是沒有沖突的。

微軟對Dispose和Finalize方法使用準則


Finalize

下面的規則概括了 Finalize方法的使用準則:

1、不能在結構中定義析構函數。只能對類使用析構函數。

2、一個類只能有一個析構函數。

3、無法繼承或重載析構函數。

4、無法調用析構函數。它們是被自動調用的。

5、析構函數既沒有修飾符,也沒有參數。

  • 僅在要求終結的對象上實現 Finalize。存在與 Finalize 方法相關的性能開銷。

  • 如果需要 Finalize 方法,應考慮實現 IDisposable,以使類的用戶可以避免因調用 Finalize 方法而帶來的開銷。

  • 不要提高 Finalize 方法的可見性。該方法的可見性應該是 protected,而不是 public。

  • 對象的 Finalize 方法應該釋放該對象擁有的所有外部資源。此外,Finalize 方法應該僅釋放由該對象控制的資源。Finalize 方法不應該引用任何其他對象。

  • 不要對不是對象的基類的對象直接調用 Finalize 方法。在 C# 編程語言中,這不是有效的操作。

  • 應在對象的 Finalize 方法中調用基類的 Finalize 方法。

注意

基類的 Finalize 方法通過 C# 和 C++ 析構函數語法自動進行調用。

釋放

下面的規則概括了 Dispose方法的使用準則:

  • 在封裝明確需要釋放的資源的類型上實現釋放設計方案。用戶可以通過調用公共 Dispose 方法釋放外部資源。

  • 在通常包含控制資源的派生類型的基類型上實現釋放設計方案,即使基類型并不需要也如此。如果基類型有 Close 方法,這通常指示需要實現 Dispose。在這類情況下,不要在基類型上實現 Finalize 方法。應該在任何引入需要清理的資源的派生類型中實現 Finalize。

  • 使用類型的 Dispose 方法釋放該類型所擁有的所有可釋放資源。

  • 對實例調用了 Dispose 后,應通過調用 GC.SuppressFinalize 方法禁止 Finalize 方法運行。此規則的一個例外是當必須用 Finalize 完成 Dispose 沒有完成的工作的情況,但這種情況很少見。

  • 如果基類實現了 IDisposable,則應調用基類的 Dispose 方法。

  • 不要假定 Dispose 將被調用。如果 Dispose 未被調用,也應該使用 Finalize 方法釋放類型所擁有的非托管資源。

  • 當資源已經釋放時,在該類型上從實例方法(非 Dispose)引發一個 ObjectDisposedException。該規則不適用于 Dispose 方法,該方法應該可以在不引發異常的情況下被多次調用。

  • 通過基類型的層次結構傳播對 Dispose 的調用。Dispose 方法應釋放由此對象以及此對象所擁有的任何對象所控制的所有資源。例如,可以創建一個類似 TextReader 的對象來控制 Stream 和 Encoding,兩者均在用戶不知道的情況下由 TextReader 創建。另外,Stream 和 Encoding 都可以獲取外部資源。當對 TextReader 調用 Dispose 方法時,TextReader 應繼而對 Stream 和 Encoding 調用 Dispose,使它們釋放其外部資源。

  • 考慮在調用了某對象的 Dispose 方法后禁止對該對象的使用。重新創建已釋放的對象是難以實現的方案。

  • 允許 Dispose 方法被調用多次而不引發異常。此方法在首次調用后應該什么也不做。

下面是CSDN高手總結


1、Finalize方法(C#中是析構函數,以下稱析構函數)是用于釋放非托管資源的,而托管資源會由GC自動回收。所以,我們也可以這樣來區分 托管和非托管資源。所有會由GC自動回收的資源,就是托管的資源,而不能由GC自動回收的資源,就是非托管資源。在我們的類中直接使用非托管資源的情況很 少,所以基本上不用我們寫析構函數。

2、大部分的非托管資源會給系統帶來很多負面影響,例如數據庫連接不被釋放就可能導致連接池中的可用數據庫連接用盡。文件不關閉會導致其它進程無法讀寫這個文件等等。

實現模型:

1、由于大多數的非托管資源都要求可以手動釋放,所以,我們應該專門為釋放非托管資源公開一個方法。實現IDispose接口的Dispose方法是最好的模型,因為C#支持using語句快,可以在離開語句塊時自動調用Dispose方法。

2、雖然可以手動釋放非托管資源,我們仍然要在析構函數中釋放非托管資源,這樣才是安全的應用程序。否則如果因為程序員的疏忽忘記了手動釋放非托管資源, 那么就會帶來災難性的后果。所以說在析構函數中釋放非托管資源,是一種補救的措施,至少對于大多數類來說是如此。

3、由于析構函數的調用將導致GC對對象回收的效率降低,所以如果已經完成了析構函數該干的事情(例如釋放非托管資源),就應當使用SuppressFinalize方法告訴GC不需要再執行某個對象的析構函數。

4、析構函數中只能釋放非托管資源而不能對任何托管的對象/資源進行操作。因為你無法預測析構函數的運行時機,所以,當析構函數被執行的時候,也許你進行操作的托管資源已經被釋放了。這樣將導致嚴重的后果。

5、(這是一個規則)如果一個類擁有一個實現了IDispose接口類型的成員,并創建(注意是創建,而不是接收,必須是由類自己創建)它的實例對象,則 這個類也應該實現IDispose接口,并在Dispose方法中調用所有實現了IDispose接口的成員的Dispose方法。

只有這樣的才能保證所有實現了IDispose接口的類的對象的Dispose方法能夠被調用到,確??梢允謩俞尫湃魏涡枰尫诺馁Y源。

————————————————————————————————————————

一個人的時候,總是在想

我的生活到底在期待什么……


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品偷伦一区二区| 一区二区三区视频在线| 亚洲女同性videos| 国产主播精品在线| 国产精品视频免费在线| 久久久久久久久久久亚洲| 精品中文字幕在线| 亚洲天堂网在线观看| 亚洲一区二区三区四区视频| 国产中文欧美精品| 丝袜情趣国产精品| 久久香蕉频线观| 久久夜色精品国产欧美乱| 国产成人自拍视频在线观看| 日韩在线观看免费高清完整版| 亚洲性线免费观看视频成熟| 欧美激情在线视频二区| 91精品国产91久久久久久吃药| 日韩av在线一区| 性色av一区二区咪爱| 91久久久亚洲精品| 欧美成人一二三| 91影视免费在线观看| 欧美日韩中文字幕在线| www.久久久久久.com| xxxxx成人.com| 欧美午夜片在线免费观看| 日本精品久久久久影院| 俺去亚洲欧洲欧美日韩| 亚洲欧洲日产国码av系列天堂| 日韩电影大全免费观看2023年上| 欧美xxxx做受欧美.88| 欧美国产日韩一区二区| 欧美性在线观看| 欧美性黄网官网| 国产精品美腿一区在线看| 精品国产乱码久久久久酒店| 欧美中文字幕在线视频| 亚洲免费av电影| 欧美国产日韩中文字幕在线| 亚洲bt欧美bt日本bt| 国产精品igao视频| 久久在精品线影院精品国产| 亚洲bt天天射| 亚洲激情在线观看| 98精品国产自产在线观看| 亚洲精品欧美日韩专区| 8090理伦午夜在线电影| 97人洗澡人人免费公开视频碰碰碰| 国产精品一区二区三区毛片淫片| 成人h猎奇视频网站| 国产999视频| 亚洲午夜未满十八勿入免费观看全集| 亚洲最大成人免费视频| 国产欧美精品在线播放| 久久久久女教师免费一区| 一区二区三区 在线观看视| 成人免费淫片aa视频免费| 欧美日韩在线观看视频| 久久伊人精品视频| 久久全球大尺度高清视频| 国产日韩欧美夫妻视频在线观看| 亚洲激情在线观看视频免费| 国产精品男女猛烈高潮激情| 91视频国产高清| 欧美国产日韩中文字幕在线| 亚洲精品一区av在线播放| 91国自产精品中文字幕亚洲| 日韩免费在线免费观看| 青青青国产精品一区二区| 在线播放精品一区二区三区| 理论片在线不卡免费观看| 国产精品第8页| 日韩av电影在线免费播放| 亚洲iv一区二区三区| 欧美一级淫片videoshd| 国产不卡av在线| 国产亚洲精品美女| 国产精品一区久久久| 亚洲欧洲国产伦综合| 成人国产精品免费视频| 亚洲性生活视频在线观看| 成人免费淫片视频软件| 国内精品久久久久久影视8| 国产精品视频网站| 日韩电影在线观看中文字幕| 91麻豆国产精品| 色777狠狠综合秋免鲁丝| 亚洲电影免费观看| 九九热精品视频国产| 精品免费在线观看| 羞羞色国产精品| 日韩中文字幕欧美| 8x海外华人永久免费日韩内陆视频| 欧美成人精品影院| 久久久久中文字幕2018| 欧美日韩在线免费| 欧美日韩人人澡狠狠躁视频| 国产欧美一区二区白浆黑人| 两个人的视频www国产精品| 92看片淫黄大片看国产片| 日韩av大片在线| 欧美黑人巨大xxx极品| 国产精品一区二区电影| 欧美亚洲视频在线观看| 欧美日韩成人在线视频| 欧美另类极品videosbestfree| 在线亚洲欧美视频| 日韩视频免费中文字幕| 国产精品直播网红| 久久久久久久999精品视频| 欧美中文在线字幕| 亚洲欧洲在线观看| 久久综合伊人77777| 日本久久亚洲电影| 成人国产亚洲精品a区天堂华泰| 中文字幕9999| 亚洲情综合五月天| 欧美成aaa人片免费看| 高清一区二区三区四区五区| 国产在线视频欧美| 欧美一区第一页| 亚洲色图13p| 欧美激情国产精品| 久久亚洲精品国产亚洲老地址| 亚洲第一国产精品| 91免费看片在线| 亚洲视频日韩精品| 亚洲视频在线观看网站| 国产精品视频最多的网站| 国产精品电影网站| 国产91免费观看| 亚洲最新中文字幕| 亚洲人成毛片在线播放| 日韩av在线资源| 亚洲视频axxx| 欧美日韩国产限制| 日韩经典中文字幕在线观看| 98精品国产高清在线xxxx天堂| 久久最新资源网| 91视频国产高清| 亚洲成人在线视频播放| 日韩有码片在线观看| 亚洲欧美变态国产另类| 欧美日韩午夜视频在线观看| 国产一区二区香蕉| 欧美极品第一页| 91久久综合亚洲鲁鲁五月天| 欧美激情中文字幕在线| 亚洲一区二区三区在线免费观看| 国产欧美久久一区二区| 国产精品www网站| 日本三级久久久| 国产精品999999| 日韩视频免费在线观看| 国产福利视频一区| 成人在线免费观看视视频| 国外成人在线视频| 久久手机精品视频| 日韩中文字幕av| 91视频国产高清| 国产精品偷伦免费视频观看的| 91精品啪在线观看麻豆免费| 日本精品久久中文字幕佐佐木|