Разработка с помощью RAD Studio (Delphi) v10.2.1 (Tokyo, выпуск 1) в Windows 10 «Creators Update», 64-разрядная версия, но 32-разрядная разработка.
Приложение представляет собой VCL с несколькими фоновыми потоками, каждый из которых использует Indy TidHTTP для получения сетевых ресурсов. Синхронизация между основным потоком и фоновыми потоками реализована с помощью очередей сообщений (вызовов PostThreadMessage). Это настолько сложно, что предлагать здесь прямой код было бы затруднительно и запутанно, поэтому я начну со словесного описания.
Что должно произойти: Откройте файл со ссылками на внешние ресурсы, это сгенерирует HTTP-запросы и передаст их в фоновую обработку, а затем дождется входящих сообщений в очереди сообщений приложения, чтобы сказать, что ресурсы были загружены. Сообщения приложения сопоставляются в коде события, назначенном TApplication.OnMessage (в этом, я подозреваю, и заключается моя проблема).
Это работает. Все чаще всего проходит гладко. Но если я открою TSaveDialog — даже если я отменю диалоговое окно, а не сделаю что-либо, — тогда сообщения пропадут из очереди сообщений приложения.
В процессе написания сообщений журнала (отладка невозможна напрямую, потому что это нарушает время, необходимое для возникновения проблемы) я выяснил, что фоновые потоки действительно публикуют сообщения (и получают положительный ответ от PostThreadMessage), но они никогда не появляется в моем коде события TApplication.OnMessage.
Я видел, что какой-то хитрый код в различных библиотеках устанавливает свои собственные циклы PeekMessage/TranslateMessage/DispatchMessage, но не все из них помнят о проверке наличия события TApplication.OnMessage. Но я только что просмотрел код VCL и дюжину или около того сторонних библиотек, которые я использую, и не нашел ни одного экземпляра этого, который мог бы попасть в этот случай (насколько я могу судить).
Примечание. Я использую madExcept, Indy, FastReport, AddictSpell, SynEdit, VclStyleUtils (среди нескольких других менее известных библиотек).
Примечание 2: мне интересно, может ли это быть связано с обновлением Delphi 10.2.1 или Windows 10 Creator, поскольку я также наблюдаю какое-то другое странное поведение (длительные задержки с первым исключением или первым TOpenDialog — но только в некоторых приложениях), которые определенно не произошло с 10.1 (я не использовал 10.2.0). ... Но это может быть (вероятно) что-то другое.
Итак, мой вопрос: что я могу сделать по этому поводу?
Любые предложения о том, как найти/проверить, что есть какой-то другой код, крадущий сообщения приложения? Что еще я должен искать, кроме PeekMessage?
Есть ли другой способ перехватить сообщения очереди сообщений приложения, которые могли бы позволить мне избежать проблемы?
Если лучшие варианты не появятся, мне, возможно, придется отказаться от использования сообщений потока приложений и внедрить свою собственную систему обмена сообщениями/синхронизации, которую я бы предпочел не делать после того, как эта другая работает очень хорошо в остальное время.
SetWindowsHookEx()
для установки хукаWH_GETMESSAGE
для конкретного потока в потоке пользовательского интерфейса. - person Remy Lebeau   schedule 31.08.2017