2009-09-22 16 views
7

Ben bazı görev yaptığını, bir arka plan iş parçacığı varken vb, yeniden boyutlandırma, etrafında iletişim taşıma gibi kullanıcıların harekete duyarlı kalmasını istediğiniz bir ana gui iş parçacığı vardır. Geçmişte, arka plan iş parçacığı üzerinde beklerken gui olaylarını işlemek için bir zaman aşımıyla WaitForSingleObject'i kullandım. Kısa bir süre önce, biraz daha temiz kaldığım sorunu çözmek isteyen MsgWaitForMultipleObjects hakkında okudum. Yanlış burada nereye gidiyorumanlama MsgWaitForMultipleObjects

Birisi bana aşağıdaki kodu & böcek söyleyebilir misiniz? Iş parçacığı başlatmak için düğmeye tıkladığınızda gui yanıt vermiyor. Ana kullanıcı arayüzünde oynayan bir avi ile bir diyalog uygulaması yaptım. Bir iş parçacığı başlatmak için bir düğmem var ve iş parçacığı iş parçacığı üzerinde beklemek için MsgWaitForMultipleObjects kullanın, ancak iş parçacığı bittiğinde/işlendiğinde en sonunda işlenecek tüm iletilere izin verin.

Teşekkürler.

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

Sen UI iş parçacığı gelen mesaj işlem görmeyen

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

cevap

13

Düğme Handler, bir örnek için (ayrıca here bakınız) look at Raymond's blog de alır. olurdu

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

Evet. Teşekkürler. –

+3

TEHLİKE Raymond'ın yazdığı hataya sahip kod. Gözetleme kafasında dönmelisin. –

+2

5 upvotes ve örnekte bazı tehlikeli hatalar var ... sabit (orijinal yazara karşı herhangi bir saldırı yok). –