2013-12-11 2 views
2

У нас есть приложение C# WinForms, которое довольно медленно и часто потребляет 50% процессорного времени.Профилирование профилей WinForms

Используя DotTrace, мы выяснили, что наиболее трудоемкие задания относятся к потоку пользовательского интерфейса. В частности, System.Windows.Forms.DataGridView.WndProc (Message &) потребляет больше всего времени.

Я знаю, что программа вызывает Invoke или BeginInvoke в элементах управления DataGridView. Это равносильно отправке сообщения в элемент управления DataGridView. Но время, затрачиваемое на вызывающий поток для отправки этих сообщений, довольно мало, наибольшее время тратится на поток пользовательского интерфейса для обработки этих сообщений.

Так dotTrace может понять, что самое трудоемкое задание находится в потоке пользовательского интерфейса, но не может определить, какие потоки отправляют эти сообщения.

Итак, что я могу сделать, чтобы найти эти темы?

+2

«У нас есть приложение для Winform C#, которое довольно медленно. Оно часто предполагает 50% процессорного времени». - действительно ? если бы он был действительно медленным, я ожидал бы, что шипы будут намного выше ... У вас есть какая-то «буря обновления UI»? Под этим я подразумеваю, обновления UI запускают другие обновления и каскад ... –

+0

@MitchWheat Да, я использовал диспетчер задач Windows для мониторинга программы. Использование ЦП всегда составляет около 50%. На самом деле, программа является торговой платформой. Он постоянно получает информацию о котировках, информацию о статусе заказа и т. Д. Извне, выполняет некоторые вычисления и затем обновляет пользовательский интерфейс. Мы пишем автоматическую торговую праграмму, поэтому она выпускает около 100 заказов каждую секунду. Мы обнаружили, что он не может быстро обрабатывать все входящие сообщения. Поэтому нам нужно выяснить, что является узким местом. Если это пользовательский интерфейс, нам нужно выяснить, что вызывает обновление пользовательского интерфейса и может замедлить частоту обновления. – rmm2014

+0

У вас может быть событие в DataGridVew, которое имеет длинные процессы и/или запускает несколько раз или, возможно, бесконечно активируется, например, когда изменяется значение ячейки или добавляется строка. – Jade

ответ

0

Прежде всего, для приложения Windows ожидается, что wndproc будет самым назойливым и трудоемким. Это сердце приложения, которое обрабатывает все. Когда вы наводите указатель мыши на мышь, это будет обработчик wndproc для почти каждого пикселя, который пересекает мышь, что довольно выделяется!

Таким образом, обработка этих событий должна быть эффективно написана. Большие операции должны быть отложены с помощью небольшого перепада времени после последнего сообщения до начала фактической операции. Извлечение источника сообщений является довольно сложной задачей, поскольку отправитель сообщений не может быть легко извлечен (обычно это ОС, если вы не вызываете BeginInvoke чрезмерно).

Одним удобным инструментом, который может дать подсказку, является SoftwareTrails. Он обеспечивает тепловую карту недавно использованных классов. Прикрепите его к одной стороне экрана, щелкая в своем приложении. Вероятно, вы увидите большую активность в пространстве имен System и Microsoft, а также меньше в своем собственном. Если нет, проверьте, обрабатываете ли вы события MouseHover или что-то в этом роде.

Это абсолютно нормально, когда wndproc является самой называемой подпрограммой в приложении Windows.

EDIT после прочтения комментариев:

Похоже, вы вызываете Invoke или BeginInvoke довольно наделите, так выглядят эти методы в вашем профилировщика и использовать колл-график, чтобы увидеть, что их вызова. Не уверен, что у DotTrace есть полный callgraph, но у него есть дерево вызовов, но вам понадобится граф, чтобы увидеть всех вызывающих абонентов, с помощью которых они называют вашу функцию. Есть много профилировщиков, которые включают call-graph.

Смежные вопросы