對象的釋放Dispose和Close對比

C#內存釋放的幾個方法對比:html

image

而Close與Dispose這兩種方法的區別在於,調用完了對象的Close方法後,此對象有可能被從新進行使用;而Dispose方法來講,此對象所佔有的資源須要被標記爲無用了,也就是此對象被銷燬了,不能再被使用。程序員

在實現Dispose方法的時候,必定要加上「GC.SuppressFinalize( this )」語句,避免再讓GC調用對象的析構函數。數據庫

 

=====================================================================函數

 

C#實現IDispose接口

 

.net的GC機制有兩個問題:首先GC並不能釋放全部資源,它更不能釋放非託管資源。其次,GC也不是實時的,全部GC存在不肯定性。
爲了解決這個問題donet提供了析構函數學習

複製代碼
複製代碼
public class TestClass : System.IDisposable
{
    //供程序員顯式調用的Dispose方法
    public void Dispose()
    {
        //調用帶參數的Dispose方法,釋放託管和非託管資源
        Dispose(true);
        //手動調用了Dispose釋放資源,那麼析構函數就是沒必要要的了,這裏阻止GC調用析構函數
        System.GC.SuppressFinalize(this);
    }

    //protected的Dispose方法,保證不會被外部調用。
    //傳入bool值disposing以肯定是否釋放託管資源
    protected void Dispose(bool disposing)
    {
        if (disposing)
        {
            ///TODO:在這裏加入清理"託管資源"的代碼,應該是xxx.Dispose();
        }
        ///TODO:在這裏加入清理"非託管資源"的代碼
    }

    //供GC調用的析構函數
    ~TestClass()
    {
        Dispose(false);//釋放非託管資源
    }
}
複製代碼
複製代碼

而即便咱們忘記了在合適的時候調用Dispose,GC也會在釋放對象的時候幫咱們清理非託管資源的。GC所充當的角色只是一種保障手段,它應該充當這種角色,咱們不能過度依賴它。實際上,在較大的模塊退出時咱們還應該及時地手動調用GC.Collect進行垃圾回收。網站

爲何實現IDisposable接口的類的對象,由於.net CLR是採用GC(垃圾回收器)機制管理內存,不想C++語言那樣,能保證對象的析構函數在做用域結束時被老是被自動調用,有時若是程序運行的過程當中一直沒有知足啓動GC的條件,則可能GC一次也沒啓動。 這樣,若是一個類須要佔用重要資源,就應該實現IDisposable接口,或者使用另外一種簡捷的方式:使用Using,如:this

Using(MyClass myObj = new MyClass())url

{ ... }spa

對於沒有實現IDisposable接口的,也就沒什麼Dispose方法,但他們的Finalize一樣不能保證被調用。

Using(MyClass myObj = new MyClass())

{ ... }

是一種好方法,可是隻有MyClass實現了IDisposable接口才能這樣寫.

 

IDispose模式在C++中用的不少,用來清理資源,而在C#裏,資源分爲託管和非託管兩種,託管資源是由C#的CLR幫助咱們清理的,它是經過調用對象的析構函數完成的對象釋放工做,而對於非託管系統來講,則須要咱們本身來釋放,例如數據庫鏈接對象,這就須要咱們手動去調用它的Dispose()方法來實現對象它的釋放,事實上,Dispose()內容到底作了什麼事,咱們並不清楚,固然這就是面向對象,它不但願你關係實現的細節,呵!

對於咱們開發人員來講,在瞭解它怎麼用以後,總會對它如何實現的產生興趣,下面,我將把C#裏實現IDispose模式的代碼展示出來,你們一塊兒來學習一下,事實上,它的使用場合也不少的,當咱們手動對網站,數據庫做封裝時,都會用的到,下面看一下代碼:

複製代碼
複製代碼
 /// <summary>
    /// 實現IDisposable,對非託管系統進行資源回收
    /// </summary>
    public class IDisplosePattern : IDisposable
    {
        public void Dispose()
        {
            this.Dispose(true);////釋放託管資源
            GC.SuppressFinalize(this);//請求系統不要調用指定對象的終結器. //該方法在對象頭中設置一個位,系統在調用終結器時將檢查這個位
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!_isDisposed)//_isDisposed爲false表示沒有進行手動dispose
            {
                if (disposing)
                {
                    //清理託管資源
                }
                //清理非託管資源
            }
            _isDisposed = true;
        }

        private bool _isDisposed;

        ~IDisplosePattern()
        {
            this.Dispose(false);//釋放非託管資源,託管資源由終極器本身完成了
        }
    }
複製代碼
複製代碼

經過上面的代碼,咱們知道了,對於託管系統(C#的CLR爲咱們管理的),直接經過~IDisplosePattern()方法進行釋放,而~IDisplosePattern()這個方法什麼時候被調用,咱們是不知道的,由於它是由CLR幫助咱們調用的,而咱們手動進行dispose方法時,它會調用dispose(true)這個重載方法,它會幫助咱們清理託管和非託管資源,如圖:

 

出處:http://www.javashuo.com/article/p-erqhcpbw-gk.html

相關文章
相關標籤/搜索