为什么GetMessageW会在我的WPF应用程序中占用大量CPU?

Dav*_*Hay 11 .net wpf performance getmessage ants

我的手上有一个严重的头疼.我正在研究我们的应用程序中的WPF组件的性能问题.

我们的.net应用程序非常庞大,几乎完全以windows形式存在.作为新计划的一部分,我们使用丰富的WPF ui重写了我们的核心组件之一.有很多WinForms < - > WPF互操作正在将这个东西粘合在一起,我怀疑这可能与我所看到的有些相关.

当我在ANTS探查器中分析慢速操作时,我发现在函数UnsafeNativeMethods.IntGetMessageW中发生了很多活动.ANTS报告了与我们所有业务逻辑和wpf渲染内容相结合的CPU活动.没有使用循环的该函数的托管代码下线,所以无论IntGetMessageW正在做什么,我都会追求.

我对win32编程并不是特别精通,但我知道在该上下文中消息循环的基础知识.我在这里看到的并不是我们手动完成的任何事情 - 在我们的代码中,我们不会直接与底层的messageloop本身或者可以在WPF调度程序上访问的任何更复杂的东西进行交互.

我们这里讨论的WPF组件是从Window继承而来的(即它不仅仅是一个控件/用户控件),我们使用ShowDialog从我们用于在此组件的旧WinForms版本上调用ShowDialog的更高级逻辑中显示它.我们在WPF组件中使用了一些WindowsFormsIntegrationHost控件,以保持与我们在WPF中无法重写的一些现有部分的兼容性.

我已经研究了好几天了,但是从来没有发现过很多东西.我一直在寻找关于输入消息(鼠标和键盘)的模糊相关帖子,但我不知道我能做些什么来验证它; 我已经尝试过屠宰代码来删除我能做的所有鼠标/键盘操作.

我很难到达任何地方,主要是因为这行代码是完全孤立的(不是我可以指出的实际来自我们的代码的任何内容的父或子),并且完全不透明它正在做什么.

这是ShowDialog函数的ANTS调用图的图像,显​​示了到达此处的调用路径: 替代文字

我完全意识到这可能是必须要作为WPF的一部分完成的事情(尽管我们在WPF中编写的其他组件不显示此行为),或者这只是ANTS探查器中的一个非常奇怪的错误,但是在这一点我需要以某种方式验证它.如果有人能告诉我这里发生了什么或者可能会发生什么 - 或者指出某些方式我能够自己解决这个问题,我将以你的方式引导各种善意的业力.

更新:在回答下面的一些讨论时,这是ANTS的另一个视图 - 这个更好地说明了我遇到的困惑(这是在"CPU时间"模式下的ANTS视图).我匆忙审查了部分代码,但没有系统相关的功能:

替代文字

谢谢你的期待!

Han*_*ant 5

是的,这是正常的。任何 GUI 应用程序始终执行 GetMessageW(),等待 Windows 向其发送消息。这样做实际上并没有消耗 CPU 周期,只是在内部同步对象上阻塞,直到发出某种 UI 事件信号。

这当然会使分析 UI 应用程序变得困难,您确实需要单元测试来测试应用程序的子组件。


Jef*_*f B 1

我在搜索同一问题的信息时发现了这一点。我将补充我所知道的内容,看看是否有帮助:

我在 WinXP 机器上运行 - WPF 框架在 Vista 和 Win7 中比在 XP 中集成得更多。部分原因可能是 WPF 在 XP 桌面“之上”运行,而不是在其中运行。

我正在运行一个纯本机 WPF 应用程序 - 没有 WinForms 或其他代码。

我遇到了这个问题,试图确定为什么简单地滚动窗口会消耗 100% CPU 并且在执行此操作时出现卡顿。

运行 AQtime 性能分析器,我发现 IntGetMessageW 占据了 100% CPU 使用率的最大部分。这不是由于 IntGetMessageW 等待消息,而是该函数实际上正在执行的操作。

我还没有研究过的一件事是,也许 IntGetMessageW 从来就不是一个快速方法,也许 WPF 只是过度使用了它。WPF 中的数据绑定可能使用本机 Win32 消息泵来更新 WPF 中的依赖关系属性。如果是这种情况,可能是我的窗口有太多绑定。