<分区>
我们有一个 C# WinForms 应用程序,它非常慢并且经常占用 50% 的 CPU 时间。
通过使用 DotTrace,我们发现最耗时的作业是在 UI 线程上。
具体来说,System.Windows.Forms.DataGridView.WndProc(Message&) 消耗的时间最多。
我知道程序调用了 DataGridView 控件上的 Invoke 或 BeginInvoke。这相当于向 DataGridView 控件发送消息。但是花在调用线程上发送这些消息的时间很少,大部分时间花在 UI 线程上来处理这些消息。
所以 dotTrace 可以找出最耗时的工作是在 UI 线程上,但它无法找出哪些线程发送了这些消息。
那么我可以做些什么来找到这些线程呢?
首先,对于 Windows 应用程序,预计 wndproc 将是调用次数最多且最耗时的方法。它是处理一切的应用程序的核心。当您将鼠标悬停在某个控件上时,它的 wndproc 处理程序将被鼠标经过的几乎每个像素调用,这是完全分配的!
也就是说,应该有效地编写这些事件的处理。在实际操作开始之前的最后一条消息之后,应该通过一个小的移位超时来延迟较大的操作。检索消息的来源是一项非常困难的任务,因为消息的发送者不容易被检索(通常是操作系统,除非您过度调用 BeginInvoke)。
一个可能提供提示的便捷工具是 SoftwareTrails .它提供了最近使用的类的热图。在您的应用程序中四处单击时,将其停靠在屏幕的一侧。您可能会在系统和 Microsoft 命名空间中看到大部分事件,而在您自己的命名空间中看到的事件较少。如果没有,请检查您是否正在处理 MouseHover 事件或其他事件。
wndproc 是 Windows 应用程序中调用次数最多的例程是完全正常的。
阅读评论后编辑:
看起来你正在调用 Invoke
或 BeginInvoke
相当多,所以在你的探查器中查找这些方法并使用调用图来查看调用它们的是什么。虽然不确定 DotTrace 是否有完整的调用图,它确实有一个调用树,但您需要一个图才能查看所有调用者以及他们调用您的函数的频率。有许多包含调用图的分析器。