等到消息循环在另一个线程上时窗口closures

在一个C ++应用程序中,我有一个窗口,其消息循环在单独的线程中运行,因为主线程正忙于计算和渲染模拟。 该窗口充当仿真的日志窗口。 当模拟引发exception时,仿真closures,日志窗口显示细节。

现在主线程应该等到日志窗口closures。 由于消息循环运行在一个单独的线程,我试图

WaitForSingleObject(logwindow->thread, INFINITE); 

从主线程。

但是,这似乎阻止了消息泵和日志窗口冻结。 那么我该如何正确地等待,直到一个窗口closures或线程结束?

ED:窗口是在主线程上创build的,但运行在不同的线程上。 我将继续并改变它,以便它也在消息循环线程上创build。

你有几个选择。

  1. 从主线程运行所有的UI,并获得工作线程同步报告回主线程显示,例如通过PostMessageSendMessage
  2. 不要等待,工作线程完成后,让工作线程向主线程发送消息。
  3. 使用MsgWaitForMultipleObjects等待。

为了详细说明MsgWaitForMultipleObjects ,它是一个等待函数,可以配置为当消息到达队列时返回。 因此,您可以保持消息泵处于活动状态,同时在处理排队的消息之间使用阻塞等待。

在伪代码中,你可以这样写:

 do { WaitResult = MsgWaitForMultipleObjects(1, hThread, TRUE, INFINITE, QS_ALLEVENTS); if (WaitResult == MessageArrivedOnQueue) PumpMessageQueue(); } while (WaitResult != WaitHandlesSignaled) 

事实上,当主线程处于阻塞等待状态时,日志窗口处于冻结状态,这表明工作线程正在向主线程发送消息,然后等待回复,但主线程已经被阻塞,无法回复。 这是两个线程经典的死锁情况。 您应该在主线程中使用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); 

我同意David的观点,你确实应该在主线程中做所有的UI工作,并在工作线程中进行计算,而不是相反。