CommandManager的WPF性能问题

Lee*_*e F 8 wpf binding wpf-controls

我们从头开始创建了一个新的,相当复杂的WPF应用程序,并且随着CommandManager注册的命令数量的增加而遇到性能问题.我们在MVVM实现中使用简单的轻量级命令,但是我们正在使用的第三方控件(Infragistics)没有,并且自由地调用CommandManager.RegisterClassCommandBinding来添加RoutedCommands.性能问题表现为在响应用户输入时UI中的感觉迟缓,例如控件之间的标签缓慢,文本输入是"生涩"而弹出动画是"笨重的".当应用程序第一次启动时,UI很快.随着更多包含Infragistics网格的屏幕打开,性能会下降.

在内部,CommandManager有一个名为_requerySuggestedHandlers的私有字段,它是List <WeakReference>.我用反射来获取对这个集合的引用,我注意到当我调用.Clear()时,UI的响应性会提升回初始状态.显然我不想去清理那些我知之甚少的收藏品,特别是使用反射(!),但我这样做是为了看看它是否能解决性能问题,并且瞧它了.

通常情况下,这种情况会在经过一段时间后自行清理.但是,WeakReferences(_requerySuggestedHandlers)的集合只会在启动垃圾收集后进行修剪,这是不确定的.因此,当我们关闭包含网格的窗口(Infragistics XamDataGrid)时,在窗口关闭很久之后,"死"网格命令的CanExecute属性将继续被不必要地评估.这也意味着如果我们关闭了许多窗口,性能仍然缓慢,直到启动垃圾收集.我知道这可能发生在分配上,而且我已经看到了自己,因为如果我打开另一个窗口,这会导致初始内存(来自处置的Windows)被收集并且性能恢复正常.

所以,鉴于上述情况,以下是我的问题:

  1. 如何以及从哪里调用CommandManager.InvalidateRequerySuggested()?我没有在MSDN上找到任何文档,可以解释这一点.我连接到CommandManager.RequerySuggested事件,看起来只要控件失去焦点就会调用它.
  2. 是否可以抑制为响应用户输入而调用CommandManager.InvalidateRequerySuggested()?
  3. 有没有其他人遇到这个问题,如果是这样,你怎么避免它?

谢谢!

Rob*_*ney 4

GC.Collect()这听起来像是确定性调用是正确做法的罕见情况之一。反对它的常见论点是垃圾收集器比你更聪明。但是当你处理WeakReference对象时,你就会进入一个你可能知道垃圾收集器不知道的东西的领域。启动垃圾收集肯定比清除更好_requerySuggestedHandlers- 除其他外,它不会对WeakReference指向仍处于活动状态的控件的对象执行任何操作。

我会选择这个而不是试图弄清楚如何抑制RequerySuggested,因为这会搞砸您仍然关心的那些命令的行为。