windows 理解 MsgWaitForMultipleObjects

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1461378/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:10:57  来源:igfitidea点击:

Understanding MsgWaitForMultipleObjects

windowsmultithreading

提问by Stephen Burke

I have a main gui thread that I want to remain responsive to the users action such as moving the dialog around, resizing, etc while I have a background thread doing some task. In the past I've used WaitForSingleObject with a timeout in order to process gui events while waiting on the background thread to complete. I recently read about MsgWaitForMultipleObjects which looked to be solving the problem that I had a little bit cleaner.

我有一个主 gui 线程,当我有一个后台线程执行某些任务时,我希望它保持对用户操作的响应,例如移动对话框、调整大小等。过去,我使用了带超时的 WaitForSingleObject,以便在等待后台线程完成时处理 gui 事件。我最近阅读了关于 MsgWaitForMultipleObjects 的文章,它看起来正在解决我更清晰的问题。

Can someone tell me the bugs in the following code & where I'm going wrong here? The gui is unresponsive when I click the button to start the thread. I made a dialog app with an avi that is playing on the main ui thread. I have a button to start a thread and use MsgWaitForMultipleObjects to wait on the thread handle but allow all messages through to be processed ultimately breaking when the thread is finished/signaled.

有人可以告诉我以下代码中的错误以及我在这里出错的地方吗?当我单击按钮启动线程时,gui 没有响应。我制作了一个带有 avi 的对话框应用程序,该应用程序在主 ui 线程上播放。我有一个按钮来启动一个线程并使用 MsgWaitForMultipleObjects 等待线程句柄,但允许处理所有消息,最终在线程完成/发出信号时中断。

Thanks.

谢谢。

UINT MyThreadProc( LPVOID pParam )
{
    ThreadData* pObject = (ThreadData*)pParam;

    if (pObject == NULL ||
        !pObject->IsKindOf(RUNTIME_CLASS(ThreadData)))
    return 1;   

    // Do some processing.
    int x = 0; 
    while (x++ < 5000)
    {
        for (int i=0; i<50000; i++)
            double sum = sqrt((double)i+1) * sqrt((double)i+2); 
    }

    return 0;
}

Button Handler

按钮处理程序

void Cmsgwait_demoDlg::OnBnClickedBtnStartThread()
{
    m_pThreadData = new ThreadData;
    CWinThread* pWorkThread = AfxBeginThread(MyThreadProc, m_pThreadData);

    m_status.SetWindowText("Status: Waiting for thread to complete."); 

    HANDLE handles[] = { pWorkThread->m_hThread }; 
    DWORD ret = 0; 

    do 
    {
        ret = MsgWaitForMultipleObjects(1, handles, FALSE, INFINITE, QS_ALLINPUT); 
        if (ret == WAIT_OBJECT_0)
        {
            m_status.SetWindowText("Status: Thread completed."); 
        }
        else if (WAIT_IO_COMPLETION)
        {
            m_status.SetWindowText("Status: User mode APC queued."); 
        }
        else if (WAIT_FAILED)
        {
            m_status.SetWindowText("Status: Wait failed"); 
        }
    }
    while (ret != WAIT_OBJECT_0 && ret != WAIT_FAILED);
}

回答by Shay Erlichmen

You are not processing the incoming message of the UI thread, take a look at Raymond's blog(also see here) for a sample.

您不是在处理 UI 线程的传入消息,请查看 Raymond 的博客(另请参阅此处)以获取示例。

  while (true) {
    switch (MsgWaitForMultipleObjects(1, &h,
                         FALSE, INFINITE, QS_ALLINPUT)) {
    case WAIT_OBJECT_0:
      DoSomethingWith(h); // event has been signalled
      break;
    case WAIT_OBJECT_0+1:
      // we have a message - peek and dispatch it
      while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
        // TODO:  must handle WM_QUIT; see Raymond's blog for details
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }
      break;
    default:
      return FALSE; // unexpected failure
    }
  }