PostMessage: сообщения не получены - PullRequest
0 голосов
/ 10 октября 2018

Мне нужны отзывы по проблеме, которую я могу обойти, но хочу лучше понять.У меня есть несколько многопоточных кода, где рабочий поток использует функцию PostMessage API Win32, чтобы опубликовать сообщение в основной поток пользовательского интерфейса для обновления TreeView.Некоторые из опубликованных сообщений иногда не отображаются через поток сообщений в потоке пользовательского интерфейса, несмотря на то, что мои записи в журнале показывают, что сообщение PostMessage вернулось успешно.

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

Я думаю (но хотел бы подтвердить), что моя проблема связана с вызовомPostMessage слишком рано в жизни потока пользовательского интерфейса.Мой WinMain вызывает CreateWindowEx для создания своего главного окна, и обработчик WM_CREATE для этого окна косвенно запускает фоновые потоки, которые довольно быстро будут вызывать PostMessage, используя HWND главных окон, возможно, даже до того, как обработчик WM_CREATE завершит работу, весьма вероятно, до прокачки сообщений WinMain

Возможно / вероятно, что некоторые сообщения в этой ситуации будут потеряны, даже если PostMessage вернул успех?В ходе тестирования я определил, что добавления небольшой задержки (Sleep (50)) в рабочий поток перед вызовом PostMessage достаточно для предотвращения потери сообщений.Однако я не уверен, что это решает основную проблему, поэтому хотел бы знать, нужно ли мне продолжать копать.

РЕДАКТИРОВАТЬ:

Во всем моем коде есть только один цикл сообщений ион не делает ничего необычного, кроме вызова обычного TranslateAccelerator и т. д .:

 // Enter the message loop
 while (GetMessage (&msg, NULL, 0, 0)) {
   if (!TranslateMDISysAccel(hwndClient, &msg) && !TranslateAccelerator (hwndFrame, hAccel, &msg)) {
     TranslateMessage (&msg) ;
     DispatchMessage (&msg) ;
   }
 }

1 Ответ

0 голосов
/ 10 октября 2018

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

Модальные циклы не отбрасывают оконные сообщения, если они не закодированы неправильно и не передают неизвестные сообщения TranslateMessage() / DispatchMessage(), как они должны.

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

Если бы это было так, PostMessage() просто потерпит неудачу, но вы уже исключили это.Как только поток вызывает любую функцию user32.dll, очередь сообщений создается и может начинать получать сообщения, даже если очередь не опрашивается сразу.

Возможно / вероятно, что некоторые сообщенияв этой ситуации будет потеряно, даже если PostMessage вернул успех?

Нет.Что-то еще происходит.Либо ваш цикл сообщений неправильно фильтрует сообщения, либо неправильно сформированный модальный цикл отбрасывает сообщения, либо вы просто отправляете неправильный HWND.Трудно сказать, поскольку вы не показывали ни одного своего кода.

В ходе тестирования я определил, что достаточно добавить небольшую задержку (Sleep (50)) в рабочий поток перед вызовом PostMessage.для предотвращения потери сообщений.

Что обычно делает ваш основной поток в течение этих 50 мс?Похоже, что-то в вашем коде пользовательского интерфейса получает и отбрасывает ваши опубликованные сообщения в течение этого времени.

С другой стороны, как потоки узнают, в какую HWND отправлять сообщения?Ваш обработчик WM_CREATE передает свой параметр hwnd потокам или потоки полагаются на HWND, возвращаемый CreateWindowEx()?В последнем случае PostMessage() должен потерпеть неудачу, если вызывается до выхода CreateWindowEx().Если ваша принимающая переменная HWND изначально не инициализирована и содержит случайное ненулевое значение, которое PostMessage() интерпретирует как действительное HWND в другом месте системы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...