问题描述
我正在处理与UI自动化相关的WPF应用程序的性能问题。
I am dealing with a performance issue an a WPF application that is related to UI Automation.
症状:
在某些计算机上,在我们的应用程序中展开一些扩展程序可以将应用程序挂起几分钟。 在其他机器上,此操作实际上是即时的。
The symptom:
On certain machines, expanding some expanders in our app can hang the app for minutes on end. On other machines this operation is effectively instantaneous.
当显示挂起时将调试器附加到进程会显示WPF正在对UIElementHelper.InvalidateAutomationAncestors执行深度递归调用。在Reflector中查看,如果ContextLayoutManager.From(base.Dispatcher).AutomationEvents.Count!= 0,则UIElement.Measure将触发对InvalidateAutomationAncestors
的调用。 添加自动化事件后设置一些断点显示这些AutomationEvents是通过WPF工具箱弹出管道添加的,当有针对某些事件注册的全局Win32事件
挂钩时。
Attaching a debugger to the process when it is apparently hung reveals that WPF is executing deep recursive calls to UIElementHelper.InvalidateAutomationAncestors. Poking around in Reflector shows that UIElement.Measure will trigger a call to InvalidateAutomationAncestors if ContextLayoutManager.From(base.Dispatcher).AutomationEvents.Count != 0. After setting some breakpoints when automation events are added shows that these AutomationEvents are added via the WPF toolip popup plumbing, when there are global Win32 event hooks registered for certain events.
所以我想我的问题归结为:
So I guess my question boils down to:
1)有没有办法保护我的应用程序,以便UI自动化不会破坏它的性能?在我正在测试的机器上,结果是Norton Antivirus导致了糟糕的交互,但是可以触发这个
行为的程序数量显然是无限制的。
1) Is there a way to protect my application so that UI Automation doesn't destroy its peformance? On the machine I was testing, it turned out that it was Norton Antivirus that had caused the bad interaction, but the number of programs that can trigger this behavior is apparently unbounded.
2)难道我们以某种方式构建了我们的应用程序,以便在UIElementHelper.InvalidateAutomationAncestors运行时触发退化行为?关于如何识别我们可能做错的事情的任何建议?
2) Could it be that we've somehow built our app such that we are triggering degenerate behavior when UIElementHelper.InvalidateAutomationAncestors runs? Any suggestions on how to identify something we may have done wrong?
推荐答案
我们已经意识到这个问题,我们将在下一个版本中修复此问题(最有可能在.NET 4.0 sp1中)。在此期间,您可以尝试以下解决方法之一
We already aware of this issue and we will be fixing this one in the next release ( most likely in .NET 4.0 sp1). In the meantime you could try one of the below workarounds
1.仅当有任何自动化客户端(如屏幕阅读器,平板电脑中的tabtip等)并且在机器中运行时,才会触发自动化代码。因此,摆脱这种情况的一种方法是关闭任何这些自动化客户端应用程序。
1. Automation code will be triggered only if there are any automation clients ( like screen reader, tabtip in tablet pcs, etc) running in the machine. So one way to get out of this situation is to close any of those automation client apps.
2.如果一个不可行,那么替代方案是, UIElementHelper .InvalidateAutomationAncestors 只有当应用程序的自动化树稀疏时才会花费更长的时间(如果使用自定义窗口禁用了建筑自动化树,则会发生这种情况;
自动化对等)并且可视化树密集。所以另一种解决方案是禁用任何自定义自动化代码,并允许WPF构建完整的自动化树。这也应该加速UIElementHelper.InvalidateAutomationAncestors。
2. If one is not feasible then an alternative is, UIElementHelper.InvalidateAutomationAncestors will take longer time only if automation tree for the app is sparse ( happens if had disabled building automation tree using custom window automation peer) and visual tree is dense. So another solution is disable any custom automation code and allow WPF to build complete automation tree. This should speed up UIElementHelper.InvalidateAutomationAncestors as well.
让我知道这是如何工作的。
Let me know how this works.
谢谢,
Rath
这篇关于由于某些机器上的UI自动化导致WPF应用程序性能不佳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!