程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> .Net確定銷毀

.Net確定銷毀

編輯:C#入門知識

.Net中,垃圾回收器負責回收你創建的引用類型的對象,但是回收時間並不能准確估計出來,所以這稱之為非確定銷毀。值類型自動釋放,所以不在本文討論之中。
       但是有些稀缺資源,比如文件句柄、數據庫連接等,就需要盡快釋放。如何做到呢。最簡單的方法就是調用GC.Collect ()強迫垃圾回收器工作。但是這種方法會降低性能,除非迫不得已。
       那麼有沒有更好的辦法?
“析構函數”
“析構函數”與c++析構函數的區別
       “析構函數”怎麼樣?比如下面的例子:
       class Class1
    {
        public Class1()
        {
            Console.WriteLine("constructor");
        }
 
        ~Class1()
        {
            Console.WriteLine("destructor");
        }
    }
       其實c#中的“析構函數”並不是c++程序員心中的析構函數,在c++中,跳出對象所生存的堆棧時或者調用delete的時候,析構函數就會被調用。c#提供了一種語法相近,但是語義完全不同的“析構函數”.實際上,該函數只是重載了System.Object類的Finalize函數。
 
       System.Object是c#中所有的類型的基類型,由於是隱式派生,所以不需要在派生列表中指定它。Finalize函數的訪問權限是protected,只能被自己和派生類使用,實際上在垃圾回收器銷毀對象時,將會給該對象一次調用Finalize的機會,這樣我們可以將自己需要的邏輯放在“析構函數”裡面。如果對象構造期間出現異常,則該方法也會被調用。
       但是,經過以上分析,可以看出,“析構函數”並不能讓我們確定銷毀某對象。
 
“析構函數”的危害
       順便說一下,C#代碼應該總是使用“析構函數”,而不是手動重載Finalize函數,因為“析構函數”會自動將內部代碼放到try塊內,並且在finnally塊內部調用base.Finalize方法。
       “析構函數”正常情況下是不建議創建的,因為它會提升該類以及被引用的其他類的代齡,這會導致垃圾回收器過早的運行,從而影響性能,同時每次垃圾回收器工作時都要額外的調用“析構函數”,這顯然也是對性能有影響的,如無必要,就不要為自己的類創建“析構函數”。
       更嚴重的情況,如果A類有“析構函數”,B類有“析構函數”,A有一個B類的變量,當垃圾回收器工作時,A和B的“析構函數”調用順序卻沒有得到保證。這樣會導致錯誤,這比性能問題更嚴重。
       Oh,my!盡量不要在“析構函數”裡面訪問托管成員變量,除非銷毀非托管資源。但是通常非托管資源都需要確定銷毀,顯然這時不能用“析構函數”解決問題。
       GC.SuppressFinalize ( )將阻止Finalize被調用。
 
 
IDisposable接口
不如提供一個方法,該方法能夠將需要提前釋放的資源釋放掉,然後該對象可以到垃圾回收器工作的時候再釋放。這就是Dispose方法。
class Class1:IDisposable
    {
        public Class1()
        {
            GC.SuppressFinalize(this);
            Console.WriteLine("constructor");
        }
 
        ~Class1()
        {
            Console.WriteLine("destructor");
        }
 
        public void Dispose()
        {
            GC.SuppressFinalize(this);
            Console.WriteLine("Dispose");
        }
}
    GC.SuppressFinalize(this);這句話告訴垃圾管理器,從現在開始,不准調用我的“析構函數,當然不能調,因為我的Dispose後面還要執行清理資源的代碼,垃圾回收器如果搶在前面將對象回收,就會出錯。如果類沒有實現“析構函數”,當然就不需要這句話了。
   
 
Close方法
為了適應大多數程序員的習慣,可以添加一個Close方法,其實內部只是調用了Dispose而已。不高興的話,也可以懶得實現它。
 
Using 方法
為了減少編寫異常處理代碼,using語法可以保證無論是否發生異常,都為調用Dispose方法或者Close方法,前提是對象支持Idisposable接口。所以這是一個很簡潔的語法。

    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved