2016-10-07 69 views
-1

我希望有一個通用(擴展)方法,它需要父控件並遍歷其所有子控件並取消訂閱它們的事件(如果有)。wpf userControl的子控件'取消訂閱事件

問題 我正在密切關注在內存消耗,當我創造了一些基於WPF的形​​式,記憶秒殺預計考慮UI元素的事件的數量和,但是當窗體關閉時我想到的內存得到釋放,在WPF ,即時通訊假設形式得到處置一旦關閉自動處置,所以GC應該清理和釋放內存......但那是什麼不發生,因爲我等了幾分鐘,並在診斷工具,看看私人內存使用情況,仍然是一樣的。所以我想知道它沒有完全處置/退訂事件等

+0

你當然可以做到這一點。但問題是:你爲什麼需要這個?請告訴我們你到目前爲止所嘗試過的。 – haindl

+0

我正在密切關注內存消耗,當我創建一些基於WPF的形​​式,內存秒殺這是預期的考慮UI元素和他們的事件的數量,但當表單關閉我期望內存得到釋放,因爲在WPF,即時通訊假設形式得到自動處置因此GC應該清理並釋放內存......但那就是我在等待幾分鐘之後發生的事情,並且在診斷工具中查看私有內存使用情況時,情況保持不變。所以我想知道它不完全處置/取消訂閱事件等。 –

+0

你應該在Visual Studio中(或藉助於其他工具)獲取一些內存快照,並查看你期望得到GCed的實例的根引用。在我的經驗中,WPF UI元素的事件處理程序通常不負責不對這些元素進行GC化。內存泄漏的一個常見原因是(例如)ResourceDictionaries的使用錯誤。通常他們會在不同的地方合併很多次,但這會導致很多不必要的情況。理想情況下,它們僅在應用程序資源中合併一次。但也可能有其他許多原因。看看根! – haindl

回答

0

我不能不管是否具有許多訂閱事件的性能產生負面影響說話,但我可以肯定的回答你的其他兩個問題:

  1. 你可以使用以下擴展名來枚舉所有的孩子:

    public static IEnumerable<T> GetVisualChildren<T>(this DependencyObject Parent) where T : DependencyObject 
    { 
        if (Parent != null) 
        { 
         for (int i = 0; i < VisualTreeHelper.GetChildrenCount(Parent); i++) 
         { 
          var Child = VisualTreeHelper.GetChild(Parent, i); 
          if (Child != null && Child is T) 
           yield return (T)Child; 
          foreach (var ChildOfChild in GetVisualChildren<T>(Child)) 
           yield return ChildOfChild; 
         } 
        } 
    } 
    
    foreach (myControlInstance.GetVisualChildren<DependencyObject>()) 
    { 
        //Unsubscribe events 
    } 
    
  2. 要取消從對象的所有事件,是指這種SO文章:

How do I unsubscribe all handlers from an event for a particular class in C#?