Подождите, пока окно не закроется, когда цикл сообщений находится в другом потоке - PullRequest
2 голосов
/ 30 июля 2011

В одном приложении C ++ у меня есть окно, цикл сообщений которого выполняется в отдельном потоке, потому что основной поток занят вычислением и рендерингом симуляции.Окно действует как окно журнала для симуляции.Когда симуляция выдает исключение, симуляция закрывается, и окно журнала отображает детали.

Теперь основной поток должен дождаться закрытия окна журнала.Поскольку цикл сообщений работает в отдельном потоке, я попытался

WaitForSingleObject(logwindow->thread, INFINITE);

из основного потока.

Однако, похоже, это блокирует рассылку сообщений, и окно журнала замирает.Итак, как правильно дождаться закрытия окна или окончания потока?

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

Ответы [ 2 ]

2 голосов
/ 30 июля 2011

У вас есть несколько вариантов.

  1. Запустите весь пользовательский интерфейс из основного потока и заставьте рабочий поток синхронизировать отчеты для отображения в главном потоке, например, через PostMessage илиSendMessage.
  2. Не ждите совсем и заставьте рабочий поток отправить сообщение в основной поток, когда рабочий будет сделан.
  3. Использовать MsgWaitForMultipleObjects для вашего ожидания.

Чтобы уточнить MsgWaitForMultipleObjects, это функция ожидания, которую можно настроить так, чтобы она возвращалась при поступлении сообщений в очередь.Таким образом, вы можете поддерживать поток сообщений, в то же время используя блокирующее ожидание между обработкой сообщений в очереди.

В псевдокоде вы должны написать его так:

do
{    
    WaitResult = MsgWaitForMultipleObjects(1, hThread, TRUE, INFINITE, QS_ALLEVENTS);
    if (WaitResult == MessageArrivedOnQueue) 
        PumpMessageQueue();
} while (WaitResult != WaitHandlesSignaled)
0 голосов
/ 30 июля 2011

Тот факт, что окно журнала зависает, пока основной поток находится в состоянии ожидания блокировки, предполагает, что рабочий поток отправляет сообщение в основной поток, а затем ожидает ответа, но основной поток уже заблокирован и не может ответить наЭто.Это классическая тупиковая ситуация для обоих потоков.Вы должны использовать MsgWaitForMultipleObjects() вместо WaitForSingleObject() в главном потоке, чтобы определить, когда новые сообщения требуют обработки во время ожидания, например:

do
{
    DWORD dwRet = MsgWaitForMultipleObjects(1, &(logwindow->thread), FALSE, INFINITE, QS_ALLINPUT);
    if (dwRet == 0xFFFFFFFF) break;
    if (dwRet == (WAIT_OBJECT_0 + 1))
    {
      process messages here...
    }
}
while (dwRet != WAIT_OBJECT_0);

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

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