2017-09-03 43 views
0

更新:在C#中配置遞歸類

對不起,但我很困惑。這可能是因爲GC/Dispose的舊觀念與新觀念的混淆。

如果你在這看這裏(儘管不再維護)官方Microsoft Documentations,表示處置模式也用於釋放託管資源:

protected override void Dispose(bool disposing) 
{ 
    if (!disposed) 
    { 
     if (disposing) 
     { 
      // Release **managed** resources. (!!!!!) 
     } 
     // Release unmanaged resources. 
     // Set large fields to null. 
     // Call Dispose on your base class. 
     disposed = true; 
    } 
    base.Dispose(disposing); 
} 

這是相反的是寫在new version,其中規定:不 需要明確釋放

託管內存(使用C#運營商新的內存分配)。它由 垃圾回收器(GC)自動發佈。

也許這只是在文檔中的一個錯誤,扔我離開(該死的微軟)。但也許 - 可能是在GC的早期階段,它不是那麼值得信任,而且指導方針是「如果你知道自己在做什麼,就可以自己清理自己」。現在,它已經非常值得信賴,指南是「在管理資源上永遠不會使用,我們比你更清楚」。如果這不是一個錯誤 - 那麼在這裏顯然會有一些變化或轉變。

至於這個問題 - 我不會做任何事情,並會讓GC做最瞭解的事情。


老問題:

我有了在它的節點,這是遞歸類一個TreeView ViewModel類(它們可以包含自己)。

例如

class RootViewModel // root 
{ 
    List<ItemViewModel> Children = new List<ItemViewModel>(); 
} 

class ItemViewModel // node 
{ 
    List<ItemViewModel> Children = new List<ItemViewModel>(); 
} 

在某些時候從樹視圖中的所有數據傳輸/保存到其他對象,我不需要TreeView的了。我猜我需要處理它? (當包含ViewModel的窗口關閉時,ViewModel類對象保存在一個靜態變量中)。

我是否需要自己處理每個節點(遞歸處理)還是足以將根對象設置爲null並調用GC?

我應該注意到我的配置沒有任何非託管資源,我只是將每個節點的Children-lists中的所有子節點設置爲null。

如此反覆 -

  1. 選項A:設置靜態對象爲null,調用GC.Collect()。
  2. 選項B:遞歸設置所有節點爲空,將靜態對象設置爲空, 調用GC.Collect()。 - 根據目前的答案和評論似乎無法解決問題
  3. 選項C:GC看到您停止使用靜態對象,因此它將自行處理它。
+3

如果您的解決方案包含強制垃圾收集的要求,那麼您正在做一些非常非常錯誤的事情。你似乎也有一些關於一次性垃圾和垃圾收集之間關係的錯誤信念;請記住,處置是釋放**而不是垃圾收集的資源**。你的選擇都不是正確的做法。 –

+0

你真的想要解決什麼問題? –

+0

@EricLippert - 我想讓我的應用程序高效和優化。我只關閉了一個窗口,並且該窗口VM使用了很多對象。我想確保他們被釋放。 –

回答

1

您應該Dispose只釋放非託管資源,例如,一些文件流。所以當你沒有任何非託管資源時,根本不需要使用Dispose。見the docs

執行與釋放, 或重置非託管資源相關的應用程序定義的任務。

取而代之的是隻要依賴GC釋放所有實例,只要沒有更多的引用存在。那就是沒有指向它的變量。所以在父節點被GC發佈的同時它的子節點(假設你沒有任何其他變量指向它們)。然而,打電話GC.Collect幾乎是總之一個壞主意,GC通常做得很好,你不應該調查。

然而,將變量設置爲null會使而不是標記爲垃圾收集,除非您有一些非常大的代碼塊(例如包含數千行的單個方法)。在這種情況下,您的變量可能很長一段時間不會超出範圍。這樣做會帶來更多的代碼異味,您應該將代碼劃分爲更小的部分來完成單一任務。

+0

正如我所提到的 - 我有一個靜態變量來保存根節點 - 它被認爲是一個參考?我需要將它設置爲null嗎? –

+1

@DavidRefaeli在靜態變量的情況下,您可以將其設置爲null,或者在應用程序終止時立即依靠GC來釋放它。 – HimBromBeere

+1

*只要沒有更多引用存在,就依靠GC釋放所有實例。那就是當沒有指向它的變量時*我知道,選擇Nitpicking,但與手頭的問題有一定關係。該規則是不可* *參考;如果它們不可訪問,則可以收集指向它的引用的對象。這使得GC可以收集彼此引用但不可訪問的對象。 – InBetween