Мое Windows Forms приложение запускает с десяток потоков, состояние работы которых отображается в списке на форме.
Отображение происходит так: каждый поток знает ссылку на форму и вызывает для неё Invoke, куда передаёт делегат функции обновления контрола.
Когда я запускаю программу, я вожу мышкой окно и наблюдаю, что оно "застревает" в своём движении. Значит -- что-то подвешивает GUI.
Сама функция обновления очень коротенькая -- просто обновляет строку и сразу возвращается. Кроме того, я отключал это обновление -- застревание продолжалось. Зато, когда я убирал из потока все операции с файлами, застревание исчезало, хотя и производилось обновление данных.
В общем, различными проверками я пришёл к выводу, что задерживает работу не мой код. Такое впечатление, что в библиотеке есть "бутылочные горлышки", то есть, методы, при запуске которых, выполнение основного потока приостанавливается.
Вот и вопрос: какими техническими средствами можно их найти?
27.09.10 11:56: Перенесено из '.NET'
Re: Как узнать, что держит интерфейс?
От:
Аноним
Дата:
24.09.10 12:48
Оценка:
Здравствуйте, dims12, Вы писали:
D>В общем, различными проверками я пришёл к выводу, что задерживает работу не мой код. Такое впечатление, что в библиотеке есть "бутылочные горлышки", то есть, методы, при запуске которых, выполнение основного потока приостанавливается.
D>Вот и вопрос: какими техническими средствами можно их найти?
Точно-точно. Вся винда этим болеет с дааавних времен. И дотнет тем более
Здравствуйте, dims12, Вы писали:
D>Сама функция обновления очень коротенькая -- просто обновляет строку и сразу возвращается. Кроме того, я отключал это обновление -- застревание продолжалось. Зато, когда я убирал из потока все операции с файлами, застревание исчезало, хотя и производилось обновление данных.
D>В общем, различными проверками я пришёл к выводу, что задерживает работу не мой код. Такое впечатление, что в библиотеке есть "бутылочные горлышки", то есть, методы, при запуске которых, выполнение основного потока приостанавливается.
D>Вот и вопрос: какими техническими средствами можно их найти?
Сколько ядер у процессора и какая его средняя загрузка при работе программы?
Что за библиотека имеется в виду? Системный I/O или сторонняя?
Здравствуйте, dims12, Вы писали:
D>В общем, различными проверками я пришёл к выводу, что задерживает работу не мой код. Такое впечатление, что в библиотеке есть "бутылочные горлышки", то есть, методы, при запуске которых, выполнение основного потока приостанавливается.
Дело может быть не только в этом, а, например, в большой загруженности процессора(ов). Поэтому всё-таки желательно показать код потоков, полный вариант с пометкой тех строк, которые Вы отключали.
Здравствуйте, Jolly Roger, Вы писали:
JR>Дело может быть не только в этом, а, например, в большой загруженности процессора(ов). Поэтому всё-таки желательно показать код потоков, полный вариант с пометкой тех строк, которые Вы отключали.
Меня интересует именно инструментарий, при помощи которого можно отловить, на чём висит поток, не только в данном случае, а вообще.
Здравствуйте, dims12, Вы писали:
D>Меня интересует именно инструментарий, при помощи которого можно отловить, на чём висит поток, не только в данном случае, а вообще.
Profiler
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, dims12, Вы писали:
D>>В общем, различными проверками я пришёл к выводу, что задерживает работу не мой код. Такое впечатление, что в библиотеке есть "бутылочные горлышки", то есть, методы, при запуске которых, выполнение основного потока приостанавливается.
D>>Вот и вопрос: какими техническими средствами можно их найти?
А>Точно-точно. Вся винда этим болеет с дааавних времен. И дотнет тем более
А может вместо обращений к файлам Sleep'ы вставить в потоки?
Здравствуйте, Sinclair, Вы писали:
D>>Меня интересует именно инструментарий, при помощи которого можно отловить, на чём висит поток, не только в данном случае, а вообще. S>Profiler
А конкретней, как в Профайлере узнать именно этот аспект? Обычно профайлеры выдают перечень функций, на которые в сумме больше всего тратится времени вообще. То есть, это может быть просто некая довольно долгая и часто работающая функция А. А мне-то надо несколько другое? Или нет?
D>А конкретней, как в Профайлере узнать именно этот аспект? Обычно профайлеры выдают перечень функций, на которые в сумме больше всего тратится времени вообще. То есть, это может быть просто некая довольно долгая и часто работающая функция А. А мне-то надо несколько другое? Или нет?
А что ещё нужно-то? Профайлер покажет функцию, в которой висит поток.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
D>> То есть, это может быть просто некая довольно долгая и часто работающая функция А. А мне-то надо несколько другое? Или нет? S> А что ещё нужно-то? Профайлер покажет функцию, в которой висит поток.
Он не висит, а подвисает. Для GUI это является неприятной особенностью, даже если зависание недолгое. А для профайлера эта функция будет просто одна из многих, он не отличит её от задержек в фоновых потоках, которые для пользователя несущественны.
Допустим, если поток фонового копирования файла задержится на 10 секунд при ожидании готовности накопителя, то профайлер эту функцию покажет впереди, как самую тормознутую. А задержка на 0.5 секунды в потоке GUI уйдёт вниз. Но именно её-то мне и надо найти!
Здравствуйте, dims12, Вы писали:
D>Мое Windows Forms приложение запускает с десяток потоков, состояние работы которых отображается в списке на форме. D>Отображение происходит так: каждый поток знает ссылку на форму и вызывает для неё Invoke, куда передаёт делегат функции обновления контрола.
Для начала просмотрите все использования Invoke — возможно, их можно заменить на BeginInvoke.
D>Вот и вопрос: какими техническими средствами можно их найти?
1. Аккуратным логгированием. Ошибки связанные с "потоками" имеют тенденцию проявляться в самые неподходящие моменты.
2. Подключиться к процессу отладчиком и посмотреть какие потоки находятся в состоянии ожидания и чего именно они ждут
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Вы можете сделать минимальный пример, демонстрирующий проблему? Я помню — Вас интересует не факт существования самой проблемы, а инструментарий для её поиска, тем не менее, хотелось-бы сначала понять, что именно должен искать этот инструментарий, а пока что это не ясно (мне).
Здравствуйте, dims12, Вы писали:
D>В общем, различными проверками я пришёл к выводу, что задерживает работу не мой код. Такое впечатление, что в библиотеке есть "бутылочные горлышки", то есть, методы, при запуске которых, выполнение основного потока приостанавливается.
D>Вот и вопрос: какими техническими средствами можно их найти?
В Visual Studio ставим выполнение программы, когда она подвисла, на паузу и смотрим в окне "Потоки" кто из потоков приложения что делает. Смотреть основной поток — он будет выполнять некий метод, который и вызывает задержку. В 99,999% случаев это будет твой код.
Здравствуйте, dims12, Вы писали:
D>Сама функция обновления очень коротенькая -- просто обновляет строку и сразу возвращается. Кроме того, я отключал это обновление -- застревание продолжалось. Зато, когда я убирал из потока все операции с файлами, застревание исчезало, хотя и производилось обновление данных.
Такое впечатление, что вы забили очередь сообщений формы своими каллбаками, но это явно не соответствует ревльности Из очевидного остаётся разные приоритеты потоков — у фонового он точно не повышен? Ну, ещё серия ССЗБ: сборка мусора — если вы её явно дёргаете, и явные блокировки.
Приведите плиз пример операций с файлами.
P.S. Вместо invoke можно обновлять UI по таймеру (не всегда возможно, но для всяких числомолотилок — обычный подход).