2015-03-31 3 views
0

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

Возникла проблема, когда DoEvents никогда не выходит. Пользовательский интерфейс реагирует (я вижу активность потоков пользовательского интерфейса в пользовательских журналах), поэтому DoEvents, похоже, накачивает сообщения, но по какой-то причине он никогда не завершается. К сожалению, этот DoEvents находится в основном компоненте обработки данных, что означает, что это прекращает обработку ответов сервера сервера, поскольку он застрял на линии DoEvents.

У нас есть трассировка секундомера, в которой указывается, как долго работали DoEvents. У меня есть журнал, в котором говорится, что он работает в течение 188267770 миллисекунд, что составляет 52 часа (глоток). Казалось, что он попал в это состояние примерно в 3 часа ночи в субботу, пока пользователь не пришел в понедельник и не закрыл приложение (не убивая процесс, я вижу, что трассировка потока графического интерфейса заканчивается изящно), после чего DoEvents завершает и данные таймера регистрируются (так что что-то, что происходит во время выключения, должно убедить DoEvents завершить).

Конечно, это происходит только на машинах пользователя производственное, а не на моем Dev поле :)

Кто-нибудь когда-нибудь видел подобную проблему к этому?

Я декомпилировал DoEvents, а также как Conrol.BeginInvoke отсылает делегаты метода к потоку GUI с помощью очереди сообщений Windows, но я не вижу, как DoEvents может застрять как это, и поддерживать пользовательский интерфейс в ответном режиме.

Исходный контроль diff также не является опцией, так как существует около 30 версий с последней «хорошей» версии, имевшейся у пользователей, и эта новая версия с проблемой - примерно 200 файлов изменились.

Большое спасибо Paul

+0

Не используйте 'DoEvents' [см. Это] (http://blog.codinghorror.com/is-doevents-evil) – SimpleVar

+2

Это одна замечательная история .. у нее есть сюжет и персонажи - где код? –

+0

Я бы предложил зарегистрировать код «основной компонент обработки данных» и просмотреть журнал, чтобы увидеть длинный список, который является вашей проблемой. Это может помочь вам определить характер проблемы. – SimpleVar

ответ

1

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

У вас есть какая-либо фоновая обработка, которая вызывает такой тип поведения? Проводка другого сообщения для продолжения обработки? Есть ли событие в системе, которое может произойти, когда обработанное может просто произойти сразу же снова?

Другой альтернативой является то, что одно из сообщений само создает вложенный цикл сообщений. Например, показ диалога приведет к тому, что цикл вложенных сообщений не завершится до тех пор, пока диалог не будет удален. Ваше приложение пытается показать диалог, который потом не будет отклонен по какой-либо причине?

Невозможно сообщить нам ответ, учитывая количество возможностей.

+0

_ «Чтобы цикл продолжал работать, в очереди сообщений должны появляться сообщения» _ - что вы подразумеваете под этим? Цикл сообщения блокирует ожидание новых сообщений, если их нет, но я бы не сказал, что цикл не работает сам по себе, больше, чем я бы сказал, что цикл 'for' или' while' больше не работает просто потому, что что-то внутри цикла ждет чего-то еще. –

+0

Он означает, что до тех пор, пока в очереди появятся сообщения, «DoEvents» продолжит выполнение, что предполагает, что сообщения добавляются в очередь как часть выполнения цикла DoEvents, на неопределенный срок. – SimpleVar

+0

Application.DoEvents() будет запускать цикл сообщений только до тех пор, пока будут отправлены сообщения. Он использует PeekMessage внутри, чтобы проверить, есть ли другое сообщение для отправки, а когда нет, оно завершается. Следовательно, для того, чтобы метод не возвращался, означает, что постоянно обрабатывается еще одно сообщение. –

1

После долгого поиска я наконец нашел причину - System.Windows.Forms.Timer.

Обычно два или более таймера могут вызвать вызов DoEvents(), чтобы никогда не заканчиваться. При обработке сообщения одного таймера WM_TIMER другой таймер может отправлять сообщение WM_TIMER, которое затем обрабатывается DoEvents, так как обрабатывается первый таймер, и т. Д.

приложение Я работаю на около 8 Таймеры я нашел до сих пор ....

Но на самом деле, DoEvents является реальным виновником, поэтому я планирую повторно-фактор, чтобы избавиться от него.

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