我有一个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....
应用程序在运行几个小时后会崩溃,所以我添加了带有匿名委托的卸载事件处理程序,以通过取消订阅用户控件的所有事件来防止内存泄漏。使用匿名委托卸载会导致内存泄漏吗?如果是,如何在不调用卸载的情况下取消订阅用户控件的所有事件?
我记得像加载、卸载这样的内部事件将由 GC 处理,对吗?
什么时候剂量匿名代表处置?
谢谢大家。
你说"应用程序在运行几个小时后会崩溃,所以我添加了卸载事件" - 这是否意味着你经常在该StackPanel中更改(添加和删除)UserControld?此外,每次创建新的用户控件时,您都会从 MainWindow 添加这些事件处理程序,对吗?
在这种情况下,您做得很好,将匿名委托分配给清理的卸载事件是留下漂亮内存占用的正确方法。
我找到了解决此问题的简单解决方案:
- 使用 and EventHandler 方法,而不是匿名委托。
-
在事件处理程序方法中调用 Unsubsribe。
..... // 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....