“措施”的性能问题

时间:2012-07-27 21:39:59

标签: wpf performance c#-4.0 gpu performance-testing

我在我的应用程序中遇到性能问题。基本上我单击一个按钮,列表中填充了数据绑定数据(这是因为大量数据而虚拟化),然后单击另一个按钮,该按钮将向相关列表视图添加一行。我很模糊,因为我觉得有必要说明UI中的实际情况。

以下是我所知道的:

  • 我没有看到我运行Win 7 Pro的强劲计算机上的问题,也没有看到具有不错规格的XP SP3计算机上的问题。我只在某个品牌的笔记本电脑(联想ThinkPad)上看到它,运行带有4 GB RAM和Core i5 CPU的Win 7企业(比XP桌面更强大)。
  • 由于上述发现,我不认为这是代码问题。
  • 我使用微软的PerfView工具进行了分析,并注意到我认为对于UIElement.Measure 的非常大量的调用(我们的代码没有直接调用),我看不到当我在其他机器上进行配置时。
  • 笔记本电脑的分辨率为1360x780,所以我认为小分辨率可能导致GPU不必要地渲染控件,因为我可能正在做一些数据绑定(这可能解释了对Measure()的大量调用)。我将笔记本电脑的显示器扩展到我的24英寸显示器,并没有看到任何改进。

现在我假设问题出在GPU上。我没有任何改进更新了驱动程序。

  1. 即使我不认为这是代码的问题,是否有相当于“SuspendLayout()”的WPF
  2. 有没有办法分析GPU性能以确定它是否在某些过程中受到重创
  3. (远拍)有没有人有过类似的计算机性能问题以及如何跟踪它们的建议?
  4. 对不起,如果这是一个模糊的问题。我试图让它符合SO的使用要求。如果您想了解更多信息,请与我们联系。

    正如附录:该程序正在使用WPF,C#4.0,问题似乎是围绕Telerik控件(尽管我认为他们不怀疑,因为我们在其他地方使用它们没有问题)。

2 个答案:

答案 0 :(得分:2)

原来这是由已知的Microsoft问题引起的。我试着解释一下,但我不会。主要是因为我做不到。

Article talking about fix(见Viðar于2010年8月3日发布的帖子):

Microsoft Hotfix网站:http://support.microsoft.com/kb/2484841/en-us

修复:http://archive.msdn.microsoft.com/KB2484841/Release/ProjectReleases.aspx?ReleaseId=5583

答案 1 :(得分:1)

1.回答

为了防止源自 WPF MeasureOverride 的大量 ContextLayoutManager 调用:

protected override void OnChildDesiredSizeChanged(UIElement el)
{
    /* base.OnChildDesiredSizeChanged(el); */       // avoid rampant remeasuring
}

2.相关引用

<块引用>

UIElement.OnChildDesiredSizeChanged(UIElement) Method
...

OnChildDesiredSizeChanged(UIElement) 方法具有对自身调用 InvalidateMeasure() 的默认实现。一个典型的实现是:做任何你自己的元素支持的优化,然后通常从代码分支的 a̲t̲ l̲e̲a̲s̲t̲ o̲n̲e̲ 调用 base OnChildDesiredSizeChanged(UIElement) ...

...暗示(和事实)是,对于由其子项中的任何一个发起的任何单父布局传递, parent 的 MeasureOverride 将被额外调用一次,并且可能额外调用一次,每个 其大小也发生变化的子代。

3.讨论

如果多个子项“同时”更改其尺寸,则父项通常会在这些调用的第一次完全检测和解释其所有 子项之间的新整体布局.这是 WPF 中的标准做法,MeasureOverride(…) 故意排除某些特定触发子项的任何指示,因此鼓励这样做。除了在大多数情况下没有这样的子项(有关详细信息,请参阅 above link)这一事实之外,它还使尝试任何类型的“部分布局”的代码变得繁琐。但最重要的是,为什么任何布局计算都想在没有首先获得最新可用测量值的情况下继续进行?

所以我们看到,在一个 MeasureOverride 调用之后,由碰巧第一个的孩子触发(这应该无关紧要),对于all,父级的布局实际上应该是最终的 其最新的儿童尺寸信息。但这并不意味着任何排队的 OnChildDesiredSizeChanged 通知(来自其大小也发生变化的其他孩子)已经消失。这些调用仍然在父进程中等待处理,除非明确放弃(如项目符号 #1 所示),否则每个调用都会生成一个额外的、现在无关的 MeasureOverride 调用。

4.警告

此处显示的代码禁用 a̲l̲l̲ 子项启动的措施失效,这适用于父项故意禁止此类更改,或本质上已经知道这些更改的情况。这并不少见;例如,它包括始终完全确定并强制执行其子项大小的任何父项,或者更一般地说,包括在其自己的度量传递期间仅从其子项采用 DesiredSize 值的任何父项。重要的是,只有自己的父级可以充分保证父级的测量。

父母可能希望取消某些孩子发起的措施通知同时保留/允许其他措施通知的情况自然取决于其他特定情况。好像比较晦涩,这里就不赘述了。