Comprendre MsgWaitForMultipleObjects

J’ai un fil de discussion principal que je veux garder sensible à l’action de l’utilisateur, comme déplacer le dialog, le redimensionner, etc. Dans le passé, j’ai utilisé WaitForSingleObject avec un délai d’attente pour traiter les événements d’interface graphique en attendant que le thread d’arrière-plan se termine. J’ai récemment lu à propos de MsgWaitForMultipleObjects qui semblait résoudre le problème que j’avais un peu plus propre.

Quelqu’un peut-il me dire les bugs dans le code suivant et où je me trompe ici? L’interface graphique ne répond pas lorsque je clique sur le bouton pour démarrer le fil. J’ai créé une application de dialog avec un fichier AVI qui joue sur le thread d’interface utilisateur principal. J’ai un bouton pour démarrer un thread et utiliser MsgWaitForMultipleObjects pour attendre sur le handle de thread mais permettre à tous les messages d’être traités en fin de compte en rupture lorsque le thread est terminé / signalé.

Merci.

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; } 

Gestionnaire de boutons

 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); } 

Vous ne traitez pas le message entrant du thread de l’interface utilisateur, regardez le blog de Raymond (voir aussi ici ) pour un exemple.

  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 } }