0

我有一个 WPF MainWindow,可以在 StackPanel 中更改(导航)UserControl:

// on code behind of MainWindow     
RootStackPanel.Children.Clear();

                UserControl1 uc1= new UserControl1();
                uc1.CustomizedEvent1+= EventHandler1;
                uc1.CustomizedEvent2+= EventHandler2;
                uc1.Loaded += (s, e1) =>
                 {
                        // Do something
                 };

                // Unsubscribe external event to prevent memory leak
                uc1.Unloaded += (s, e1) =>
                    {
                        uc1.CustomizedEvent1 -= EventHandler1;
                        uc1.CustomizedEvent2 -= EventHandler2;
                    };
RootStackPanel.Children.Add(uc1);

// same for UserControl 2,3,4....

应用程序将在运行几个小时后崩溃,所以我添加了带有匿名委托的 Unloaded 事件处理程序,以通过取消订阅 UserControl 的所有事件来防止内存泄漏。Unloaded with Anonymous Delegate 会导致内存泄漏吗?如果是,如何在不调用 Unloaded 的情况下取消订阅 UserControl 的所有事件?

我记得像 Loaded, Unloaded 这样的内部事件会被 GC 处理,对吧?

匿名代表何时处置?

谢谢大家。

4

2 回答 2

0

你说“应用程序在运行几个小时后会崩溃,所以我添加了 Unloaded 事件”——这是否意味着你经常在 StackPanel 中更改(添加和删除)UserControld?此外,每次创建新的 UserControl 时,都会从 MainWindow 添加这些事件处理程序,对吗?

在这种情况下,您一切正常,并为 Unloaded 事件分配一个匿名委托,该事件清理是留下良好内存足迹的正确方法。

于 2013-10-09T06:59:36.447 回答
0

我找到了一个简单的解决方案来解决这个问题:

  • 使用和 EventHandler 方法而不是匿名委托。
  • 在 EventHandler 方法中调用取消订阅。

    .....
    // on code behind of MainWindow     
    RootStackPanel.Children.Clear();
    
            UserControl1 uc1= new UserControl1();
            uc1.CustomizedEvent1+= EventHandler1;
            uc1.CustomizedEvent2+= EventHandler2;               
    
            // Unsubscribe external event to prevent memory leak
            //uc1.Unloaded += (s, e1) =>
             //   {
             //       uc1.CustomizedEvent1 -= EventHandler1;
             //       uc1.CustomizedEvent2 -= EventHandler2;
             //   };
    RoutedEventHandler unloadedHandler = null;
    unloadedHandler = delegate(object s, RoutedEventArgs sev)
        {
     uc1.CustomizedEvent1 -= EventHandler1;
             uc1.CustomizedEvent2 -= EventHandler2;
    uc1.Unloaded -= unloadedHandler;
    };
        uc1.Unloaded += unloadedHandler;
    RootStackPanel.Children.Add(uc1);
    // same for UserControl 2,3,4....
    
于 2013-10-09T10:02:33.670 回答