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

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

.net非托管資源的回收

2019-11-14 16:23:24
字體:
來源:轉載
供稿:網友

釋放未托管的資源有兩種方法

 

1、析構函數

2、實現System.IDisposable接口

 

一、析構函數  

構造函數可以指定必須在創建類的實例時進行的某些操作,在垃圾收集器刪除對象時,也可以調用析構函數。析構函數初看起來似乎是放置釋放未托管資源、執行一般清理操作的代碼的最佳地方。但是,事情并不是如此簡單。由于垃圾回收器的運行規則決定了,不能在析構函數中放置需要在某一時刻運行的代碼,如果對象占用了寶貴而重要的資源,應盡可能快地釋放這些資源,此時就不能等待垃圾收集器來釋放了.  

實例

 
C# 代碼   復制
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()方法 看下這段代碼中對于析構函數的編譯:

 
C# 代碼   復制
.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 

 

使用析構函數來釋放資源有幾個問題

 

1、與C++析構函數相比,C#析構函數的問題是他們的不確定性。在刪除C++對象時,其析構函數會立即執行,但是由于垃圾收集器的工作方式,無法確定C#對象的析構函數何時執行。

2、C#析構函數的執行會延遲對象最終從內存中刪除的時間。有析構函數的對象需要2次處理才能刪除:第一次調用析構函數時,沒有刪除對象,第二次調用才真正刪除對象。

 

二、IDisposable接口

IDisposable接口定義了一個模式,為釋放未托管的資源提供了確定的機制,并避免產生析構函數固有的與垃圾函數器相關的問題。IDisposable接口聲明了一個方法Dispose(),它不帶參數,返回void。

 

1、MSDN建議按照下面的模式實現IDisposable接口

 
C# 代碼   復制
 public class Foo: IDisposable
 {     public void Dispose()     {        Dispose(true);        GC.SuppressFinalize(this);     }       protected virtual void Dispose(bool disposing)     {        if (!m_disposed)        {            if (disposing)            {               // Release managed resources            }              // Release unmanaged resources              m_disposed = true;        }     }       ~Foo()     {        Dispose(false);     }       private bool m_disposed; }

 

.NET的對象中實際上有兩個用于釋放資源的函數:Dispose和Finalize

 

(1)、Finalize的目的是用于釋放非托管的資源,而Dispose是用于釋放所有資源,包括托管的和非托管的

 

(2)、void Dispose(bool disposing)函數通過一個disposing參數來區別當前是否是被Dispose()調用

如果是被Dispose()調用,那么需要同時釋放托管和非托管的資源。如果是被~Foo()(也就是C#的Finalize())調用了,那么只需要釋放非托管的資源即可。

 

(3)、Dispose()函數是被其它代碼顯式調用并要求釋放資源的,而Finalize是被GC調用的

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

 

然而,即使重復調用Finalize和Dispose也是不存在問題的,因為有變量m_disposed的存在,資源只會被釋放一次,多余的調用會被忽略過去。

 

Finalize、Dispose保證了

 

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

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

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

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

 

 

 

 

2、IDisposable例子

 

 
C# 代碼   復制
namespace 資源回收
{    class Program    {        static void Main(string[] args)        {            //使用using對實現IDisposable的類了進行資源管理/*拿到一個對象的時候,首先判斷這個對象是否實現了IDisposable接口,如果實現了,最好就用using包裹住這個對象,保證這個對象用完之后被釋放掉,否則很可能出現資源泄露的問題*/            using (Telphone t1 = new Telphone())            {                t1.Open();                t1.Speak("hello");                t1.Bomb();                //t1.Dispose();//如果在這里調用了Dispose()方法釋放資源,那么在執行t1.Open()方法就出錯,電話線已經被剪斷了,無法再打電話了                t1.Open();                t1.Speak("I am back!");            }//代碼執行到這里后,就會調用Dispose方法來進行資源回收            Console.ReadKey();        }    }    /// <summary>    /// Telphone類實現了IDisposable接口    /// </summary>    class Telphone : IDisposable    {        /// <summary>        /// 電話狀態        /// </summary>        private TelphoneState state;        /// <summary>        /// 打電話        /// </summary>        public void Open()        {            if (state == TelphoneState.Disposed)            {                throw new Exception("電話線已經被剪斷,無法打開!");            }            state = TelphoneState.Open;            Console.WriteLine("拿起電話");        }        /// <summary>        /// 說話        /// </summary>        /// <param name="s">說話內容</param>        public void Speak(string s)        {            if (state != TelphoneState.Open)            {                throw new Exception("沒有連接");            }            Console.WriteLine(s);        }        /// <summary>        /// 掛掉電話        /// </summary>        public void Bomb()        {            state = TelphoneState.Close;            Console.WriteLine("掛掉電話");        }        IDisposable 成員    }    /// <summary>    /// 電話狀態枚舉    /// </summary>    enum TelphoneState    {        Open, Close, Disposed    }}

 

程序運行結果:

 

 

 

 

三、析構函數和IDisposable混合調用的例子

 

 
C# 代碼   復制
public class ResourceHolder : IDisposable
{      private bool isDispose = false;            // 顯示調用的Dispose方法  public void Dispose()       {           Dispose(true);          GC.SuppressFinalize(this);        }       // 實際的清除方法  protected virtual void Dispose(bool disposing)       {            if (!isDisposed)           {              if (disposing)            {                       // 這里執行清除托管對象的操作.                  }                  // 這里執行清除非托管對象的操作            }             isDisposed=true;      }      // 析構函數       ~ResourceHolder()      {            Dispose (false);      }}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美性在线观看| 欧美激情精品久久久久久黑人| 亚洲国产精品电影在线观看| 国产精品jvid在线观看蜜臀| 中文字幕一区二区三区电影| 日本高清+成人网在线观看| 日韩精品在线视频| 欧美乱人伦中文字幕在线| 中文字幕国产精品久久| 俺去了亚洲欧美日韩| 国产一区二区三区精品久久久| 欧美激情按摩在线| 欧美日韩亚洲国产一区| 97久久精品人人澡人人爽缅北| 久久久免费精品| 激情成人中文字幕| 日韩中文字幕久久| 久久久久久av| 亚洲伊人第一页| 国产一区二区三区精品久久久| 欧美成人中文字幕在线| 欧美韩国理论所午夜片917电影| 欧美疯狂xxxx大交乱88av| 国产精品欧美久久久| 欧美日韩中文在线观看| 欧美日韩激情美女| 亚洲电影免费观看高清完整版在线观看| 亚洲精品国产美女| 色婷婷综合成人| 欧美日韩国产一区中文午夜| 亚洲开心激情网| 国产又爽又黄的激情精品视频| 91欧美精品午夜性色福利在线| 伊人伊人伊人久久| 欧美精品中文字幕一区| 国产精品精品视频一区二区三区| 欧美国产第二页| 日本午夜在线亚洲.国产| 亚洲美女又黄又爽在线观看| 日韩av免费观影| 亚洲性夜色噜噜噜7777| 奇门遁甲1982国语版免费观看高清| 日韩成人av在线| 亚洲欧美日韩一区在线| 亚洲免费电影一区| 欧美日韩国产精品一区| 欧美裸体男粗大视频在线观看| 国产+成+人+亚洲欧洲| 久久99国产精品久久久久久久久| 亚洲免费影视第一页| 懂色av中文一区二区三区天美| 国产成人啪精品视频免费网| 欧洲精品毛片网站| 日韩中文字幕在线视频| 欧洲永久精品大片ww免费漫画| 国产91热爆ts人妖在线| 日韩中文理论片| 91久久在线视频| 欧美日韩国产综合新一区| 色妞欧美日韩在线| 丝袜情趣国产精品| 午夜精品在线视频| 国产主播欧美精品| 欧美日韩亚洲高清| 国产一区二区欧美日韩| 国产精品美腿一区在线看| 欧美日韩另类视频| 亚洲aⅴ男人的天堂在线观看| 日本中文字幕成人| 91久热免费在线视频| 日韩精品视频在线播放| 精品欧美一区二区三区| 国产精品99蜜臀久久不卡二区| 国产精品美女久久久免费| 国内外成人免费激情在线视频网站| 日韩免费不卡av| 日韩av在线影院| 国产日韩欧美影视| 亚洲精品自在久久| 国产精品黄页免费高清在线观看| 中文日韩在线视频| 97国产一区二区精品久久呦| 精品国产91久久久久久老师| 成人激情在线观看| 92裸体在线视频网站| 成人国产精品色哟哟| 欧美一级淫片播放口| 亚洲人成毛片在线播放| 91九色精品视频| 精品亚洲男同gayvideo网站| 欧美日韩激情美女| 91国语精品自产拍在线观看性色| 亚洲视频一区二区| 性欧美激情精品| 日本久久久久久久久| 欧美视频国产精品| 日韩成人激情视频| 国产精品一区电影| 国产欧美日韩高清| 国产精品久久久久久久久免费| 97香蕉超级碰碰久久免费的优势| 在线不卡国产精品| 日本伊人精品一区二区三区介绍| yellow中文字幕久久| 亚洲人成网7777777国产| 久国内精品在线| 91在线免费看网站| 日韩av网站大全| 国模吧一区二区| 欧美xxxx14xxxxx性爽| 爽爽爽爽爽爽爽成人免费观看| 欧美激情奇米色| 欧美日韩爱爱视频| 色偷偷亚洲男人天堂| 久久久精品免费| 少妇激情综合网| 九九视频这里只有精品| 日韩精品在线免费| 色偷偷噜噜噜亚洲男人的天堂| 国产欧美在线视频| 黑人巨大精品欧美一区二区一视频| 成人a视频在线观看| 一区二区在线免费视频| 国产精品女主播视频| 日韩电影中文字幕在线观看| 九九久久综合网站| 亚洲女人天堂av| 欧美性猛交xxxx| 日韩电影网在线| 亚洲自拍偷拍一区| 欧美性xxxxx极品| 亚洲小视频在线观看| 国产日韩在线观看av| 欧美在线观看网址综合| 国产精品久久婷婷六月丁香| 亚洲精品久久7777777| 成人激情视频在线播放| 亚洲激情自拍图| 青草热久免费精品视频| 国产成人精品一区二区| 久久成人在线视频| 国产欧美精品一区二区| 91视频国产精品| 亚洲精品在线看| 深夜福利亚洲导航| 亚洲免费人成在线视频观看| 亚洲精品美女在线观看播放| 国产精品久久久久久久久久尿| 中文字幕日韩av电影| 成人免费午夜电影| www.欧美精品一二三区| 欧美大全免费观看电视剧大泉洋| 97热精品视频官网| 欧美成人剧情片在线观看| 亚洲免费视频网站| 在线中文字幕日韩| 九色精品免费永久在线| 欧美一级电影在线| 欧美日韩在线免费| 热re91久久精品国99热蜜臀| 欧美激情国产精品| 亚洲欧美日韩中文视频| 亚洲视频自拍偷拍| 亚洲欧美日韩国产中文专区|