2009-09-22 3 views
7

나는 내가 어떤 작업을하고 백그라운드 스레드가 동시에 등등, 크기 조정, 주변의 대화를 이동로 사용자의 동작에 반응을 유지하려는 기본 GUI 스레드를 가지고있다. 과거에는 WaitForSingleObject를 사용하여 백그라운드 스레드가 완료 될 때까지 대기하면서 GUI 이벤트를 처리했습니다. 나는 최근에 MsgWaitForMultipleObjects에 대해 읽었는데,이 MsgWaitForMultipleObjects는 내가 조금 더 깨끗한 문제를 해결할 것으로 보였다. 내가 잘못 여기거야 어디이해 MsgWaitForMultipleObjects

은 누군가가 나에게 다음 코드 &에서 버그를 말할 수 있습니까? 스레드를 시작하기 위해 버튼을 클릭하면 GUI가 응답하지 않습니다. 메인 UI 스레드에서 재생중인 avi로 대화 앱을 만들었습니다. 내가 스레드를 시작하고 궁극적으로 스레드가 완료되면 차단 처리에 이르기까지 모든 메시지를 스레드 핸들을 기다려야 만 할 수 있도록 MsgWaitForMultipleObjects를 사용할 수있는 버튼이/렸습니다.

감사합니다.

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

당신은 UI 스레드의 수신 메시지를 처리하지 않는

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

답변

13

단추 처리기, 샘플은 (또한 here 참조) look at Raymond's blog에 걸릴. 그것을 것

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

그래. 감사. –

+3

위험 이것은 Raymond가 적어 놓은 버그가있는 코드입니다. peekmessage를 반복해야합니다. –

+2

5 upvotes 샘플은 위험한 버그가 ... 고정 (원본 작성자에게 악의). –