我们从头开始创建了一个新的、相当复杂的 WPF 应用程序,但随着使用 CommandManager 注册的命令数量增加,我们遇到了性能问题。我们在我们的 MVVM 实现中使用了简单的轻量级命令,但是我们使用的第三方控件(Infragistics)没有,并且可以自由地调用 CommandManager.RegisterClassCommandBinding 来添加 RoutedCommands。当响应用户输入时,性能问题表现为 UI 中的感知迟缓,例如控件之间的选项卡很慢,文本输入“生涩”,弹出动画“笨拙”。当应用程序第一次启动时,用户界面非常活泼。随着打开更多包含 Infragistics 网格的屏幕,性能会下降。
在内部,CommandManager 有一个名为 _requerySuggestedHandlers 的私有(private)字段,它是一个 List
通常,这种情况会在经过一定时间后自行清理。但是,WeakReferences (_requerySuggestedHandlers) 的收集只会在垃圾收集启动后被修剪,这是不确定的。因此,当我们关闭包含网格的窗口 (Infragistics XamDataGrid) 时,“死”网格命令的 CanExecute 属性会在窗口关闭很久之后继续进行不必要的评估。这也意味着,如果我们关闭多个窗口,在启动垃圾收集之前,性能仍然很慢。我知道这可能在分配时发生,而且我自己也看到过,因为如果我打开另一个窗口,这会导致初始内存(来自已处理的 Windows)被收集并且性能恢复正常。
因此,鉴于上述情况,这是我的问题:
谢谢!
最佳答案
这听起来像是确定性调用 GC.Collect()
的罕见情况之一。是正确的做法。反对它的普通论点是垃圾收集器比你更聪明。但是当你处理 WeakReference
对象,你进入了你可能知道垃圾收集器不知道的东西的领域。启动垃圾收集肯定比清除 _requerySuggestedHandlers
更好。 - 除其他外,它不会对 WeakReference
做任何事情指向仍然存在的控件的对象。
我会选择这个而不是试图弄清楚如何抑制 RequerySuggested
,因为这会破坏您仍然关心的那些命令的行为。
关于CommandManager 的 WPF 性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5144352/