簡體   English   中英

在 C# 中處理和設置對 null 的引用有什么區別?

[英]What is the difference between Dispose and setting reference to null in C#?

我有兩個代碼示例,我想知道它們之間的區別是什么,哪個更適合用作最佳實踐和性能方面:

using (TestForm test = new TestForm())
{
test.ShowDialog();
}

另一個是:

TestForm test = null; 
try
{
test = new TestForm();
 test.ShowDialog();
}
catch(Exception ex)
{
}
finally
{
test = null; 
}

IDisposable 接口定義了 Dispose 方法,以及使用“使用”語法的可能性。 可以實現 class 的 dispose 方法來釋放資源、關閉數據庫連接以及任何類型的終結和清理。 僅將 class 實例設置為 null 不會執行 dispose 方法中定義的任何代碼。 作為一般規則,如果 class 實現 IDisposable,則應在完成 class 實例后調用 dispose。

Dispose()用於釋放非托管資源。 可以在終結器(可能調用Dispose() )中完成,但不要依賴它。 如果沒有完成,那么您會泄漏非托管資源。

設置對null的引用僅意味着特定引用不再指向該 object。 在那之后它可以存在很長一段時間(如果你有另一個引用,甚至可以無限期地存在 - 好吧,如果你多次引用你Dispose() d 的 object,那么它可能會變得丑陋)。

一般來說,當你完成它們時,總是在IDiposable上調用Dispose() 如果將它們包裝到using語句中會更容易:

using (var foo = new SomeDiposableObject()) {
  // do something with foo
}

IDisposable模式是一種及時釋放 object 可能正在消耗的非托管和托管資源的機制。

該模式的典型實現方式如下:

public void Dispose() //Implementes the IDisposable interface
{ 
    this.Dispose(true);
    GC.SupressFinalize(this); //All resources have been released, no need to run the finalizer. We make the GC's life a little easier;
} 

protected void Dispose(bool disposing)
{
     if (disposing)
     {
        //Relesase managed resources.
     }

    //Release unmanaged resources.
}

~MyDisposableObject()  //finalizer
{
    this.Dispose(false)
}

這里要注意的是,通過Dispose方法釋放資源與您在邏輯上期望在finalizer中找到的非常相似。 由於兩個主要原因,它沒有直接在終結器中完成:

  1. 終結器不是以確定的順序執行的。 這就是為什么我們不從終結器 ( Dispose(false) ) 中釋放托管資源的原因,因為 object 持有的部分或全部托管資源可能在 object 本身之前已經完成。 對於非托管資源,情況並非如此,因為根據定義,它們永遠不會被GC最終確定。

  2. 我們不知道終結器何時運行(取決於GC )。

基本思想是,實現IDisposable的 object 是任何消費者說的一個標志:“嘿,我持有一定數量的非托管和/或托管資源,這些資源最終將在GC決定我不再釋放時釋放有用,但如果您需要及時收回這些資源,請致電 Dispose(),我很樂意提供幫助。 ”。

另一方面,將引用變量設置為null根本不會釋放任何資源。 如果您從 object 中刪除的引用是唯一一個對所述 object 的引用,那么 object 最終將被GC收集並且托管和非托管資源將被釋放(何時,有人猜測)

如果還有更多的活動引用仍然指向 object,那么 object 將繼續存在,並且不會釋放任何資源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM