我有一个WPF窗口打开一个模态子窗口来加载一些数据。两个窗口都有自己的视图模型,现在我遇到了这个问题:关闭子窗口后,它似乎仍然在后台运行!
要关闭子窗口,我从viewmodel命令设置了DialogResult;现在,如果我创建一个新数据,然后我从父窗口编辑它(之前关闭子窗口),子窗口仍然捕获以前绑定的属性的属性更改事件。
如何避免这种情况?
关闭模态窗口时,我会清除每个带数据的引用。这是最好的做法吗?
答案 0 :(得分:3)
确保不保留对窗口的任何引用,即使是间接引用也是如此。泄漏的最常见原因之一是事件。如果窗口B正在向窗口A的事件添加事件处理程序,则在A也是B之前不会释放B.
例如,如果您直接收听属性更改,则应使用Weak Event Pattern并将所有+ =替换为PropertyChangedEventManager。AddListener。通常,应删除添加到事件中的每个强处理程序以避免泄漏。
有关this MSDN article中.NET泄漏的更多信息。
您可以使用像Scitech的mem profiler或Jetbrains dotTrace这样的内存分析器来查看将窗口保存在内存中的对象。
编辑:为了回应您的评论,您的案例比我原先想象的要简单得多:垃圾收集器根本没有收集窗口。在GC.Collect
上添加Test_Click
用于测试目的可以解决问题。
此处,在表单关闭时从SelectionChanged
中删除ComboBox
事件,这样您就可以让GC完成其工作并在以后回收表单而不会出现问题。如果您真的需要立即发布整个表单,可以考虑调用GC.Collect
尽管您应该尽可能避免使用它。
编辑2:为了回应您的第三条评论,它应该只对视图之间共享的对象以及视图中的更改将在共享对象中更改某些内容的位置有关。在您的测试项目中,SelectionChanged
在原始列表中不执行任何操作,因此无论事件是否被引发都无关紧要。表格最终将被收集。