Почему событие Winforms Click медленнее, чем событие MouseClick? - PullRequest
7 голосов
/ 11 сентября 2010

Я добавляю кнопки в форму с помощью цикла и заметил, что добавление обработчиков событий клика слишком сильно замедляет работу приложения. Позже я попробовал событие щелчка мыши вместо события щелчка, и оно работает мгновенно.

На этом скриншоте показаны результаты моего теста: alt text Исходный код: http://pastebin.com/qVewNm1u

Результаты для обработчика событий 1000:
Нажмите: 2892мс MouseClick: 1 мс

Я не могу понять, почему событие Click происходит очень медленно.

Edit: Если я изменю цель платформы сборки на x64 или Any CPU, результаты изменятся: Нажмите: 5, MouseClick: 9 Выглядит как цель платформы x86, вызывающая эту проблему, но результаты x64 тоже не очень хорошие по сравнению с x86 MouseClick Time (1ms).

Edit2: Я изменил скриншот, теперь он покажет лучший результат.

Edit3: https://connect.microsoft.com/VisualStudio/feedback/details/597039/winforms-click-event-slower-than-the-mouseclick-event

Ответы [ 4 ]

5 голосов
/ 11 сентября 2010

Репро, но это специфично для VS2010. В VS2008 такого поведения нет, оба выполняются менее чем за 1 такт. Это также не зависит от версии .NET.

Это похоже на дефект в IntelliTrace, доступный в версии Ultimate. Попытка копнуть глубже и включение отладки неуправляемого кода убрали эффект. Project + Properties, вкладка Debug, отметьте галочкой «Включить отладку неуправляемого кода». Кроме того, запуск программы без отладчика (Ctrl + F5) убрал эффект. Slam-dunk: Инструменты + Параметры, IntelliTrace, Общие, снимите флажок Включить, чтобы удалить эффект.

Я рекомендую опубликовать свои выводы на connect.microsoft.com. Вы можете сослаться на эту тему в своем отзыве. Все, что им нужно знать для диагностики проблемы, доступно.

Как уже отмечалось, временное решение заключается в отключении IntelliTrace. Это гарантированно не будет проблемой на машине вашего клиента.

0 голосов
/ 11 сентября 2010

Хотя я не могу сказать вам, что происходит, у вас есть ряд проблем с вашим набором тестов.

Во-первых, вам, вероятно, следует остановить таймер перед выполнением Console.WriteLine, поскольку теперь вы также измеряете, сколько времени потребуется для создания строки, используемой в WriteLine.

Во-вторых, вы можете создать кнопки перед запуском таймера, поскольку вы также измеряете время создания кнопки, которое включает в себя стек, кучу, сборку мусора и другие потенциальные проблемы. Я бы предложил выделить кнопки для массива, а затем назначить четные обработчики для элементов после запуска секундомера.

0 голосов
/ 11 сентября 2010

Я не уверен, потому что у меня только 4 мс для ClickTest (). Однако я изменил код на это, и время 4 мс прошло.

EventHandler d = new EventHandler(Form1_Click);
for (int i = 0; i < buttons.Length; i++) buttons[i].Click += d;

Код в цикле, который вы написали, эквивалентен button[i].Click += new EventHander(Form_Click), который создает новый экземпляр делегата на каждой итерации.

0 голосов
/ 11 сентября 2010

Пробовали ли вы сначала создать кнопки, прежде чем измерять вложение обработчика событий?

Здесь есть как минимум два неизвестных: 1) время выполнения конструктора кнопки и 2) подписка на обработчик событий.

Обновление: Я попытался воспроизвести проблемуно я последовательно получаю 4ms-6ms для обоих тестов.Один тест всегда медленнее, или это произошло только один раз?Иногда с джитингом и GCing случаются странные вещи, которые не всегда на 100% детерминированы.

...