我在usercontrol中有以下代码行:
Application.Current.RootVisual.MouseLeftButtonDown += RootClicked;
当定义了父用户控件不再由GC收集或销毁时,RootClicked事件即使在不再处于活动状态后仍会继续触发。
如果我添加:
Application.Current.RootVisual.MouseLeftButtonDown -= RootClicked;
问题已不复存在。
为什么会这样?是否有一个函数我应该明确删除该事件?
答案 0 :(得分:3)
这是一种正常行为,是.NET中常见的内存泄漏源。
当您将对象A的实例方法附加到对象B的事件时,您在事件接收器列表中添加A的实例,因此垃圾收集器无法释放对象A,直到您删除处理程序或您释放对象A和B的每个引用。 这是一种预期的正常行为。
解决问题的方法有两种:
1)当您不再需要对象A时,您可以从事件中取消订阅对象A.
2)你使用像WPF那样的弱事件。 弱事件通常使用WeakReference类实现,您可以在Web上找到更多信息。
答案 1 :(得分:1)
这是一种已知行为,但大多数开发人员并未意识到这一点。您应该查看Weak Event Pattern以获取有关如何以更优雅(如果编码密集程度更高)的方式解决此限制的信息,而不是必须手动删除事件处理程序。