MFC 主介面函式中執行緒等待避免介面卡死的處理方法

十日十乞001發表於2017-06-01

實用場景:

例如在MFC主介面某個Button Click事件中起一個執行緒去做處理一些事情,在起的執行緒執行完畢後,接著跑Click起執行緒後的程式碼,已達到按順序執行,保證時許正確的目的。

問題:

通常處理一個執行緒等待用 WaitForSingleObject,這個放在主介面執行緒成中會造成主介面“卡死”,其原因是它將主介面的訊息迴圈給阻塞了,即等不到執行緒結束的時候介面上的訊息迴圈無法正常工作,從而造成介面“卡死”

處理辦法:

在等待執行緒的同時,讓訊息迴圈一直工作


示例


[cpp] view plain copy
  1. UINT CMainUIThreadWaitDlg::StartThread(LPVOID pParam)  
  2. {  
  3.     ((CMainUIThreadWaitDlg*)pParam)->ThreadWork();  
  4.     return 0;  
  5. }  
  6.   
  7. void CMainUIThreadWaitDlg::ThreadWork()  
  8. {  
  9.     OutputDebugString(_T("+++++Start+++++\r\n"));  
  10.     Sleep(20*1000);  
  11.     OutputDebugString(_T("++++++End+++++\r\n"));  
  12. }  
  13.   
  14. void CMainUIThreadWaitDlg::DoEvent()  
  15. {  
  16.     MSG msg;  
  17.     if(::PeekMessage(&msg,NULL,0,0,PM_REMOVE))  //取訊息,檢索應用程式的訊息佇列,PM_REMOVE取過之後從訊息佇列中移除  
  18.     {  
  19.         //發訊息  
  20.         ::TranslateMessage(&msg);   
  21.         ::DispatchMessage(&msg);  
  22.     }  
  23. }  
  24.   
  25. CWinThread* pThread = NULL;  
  26.   
  27. void CMainUIThreadWaitDlg::OnBnClickedBtnWork()  
  28. {  
  29.     m_btnWork.EnableWindow(FALSE);      //按鈕禁灰  
  30.     pThread = AfxBeginThread(StartThread,this);  //起執行緒  
  31.     DWORD dwRet;  
  32.     DoEvent();  
  33.     do   
  34.     {  
  35.         dwRet = ::MsgWaitForMultipleObjects(1, &pThread->m_hThread, FALSE, INFINITE, QS_ALLINPUT);  
  36.         if (dwRet != WAIT_OBJECT_0)  
  37.         {  
  38.             DoEvent();  
  39.         }  
  40.     } while ((dwRet != WAIT_OBJECT_0) && (dwRet != WAIT_FAILED));  
  41.     m_btnWork.EnableWindow(TRUE);       //按鈕點亮  
  42. }  

相關文章