妙博客

主机评测 香港服务器 洛杉矶VPS测评

VC/MFC 避免主线程卡死

实用场景:


例如在MFC主界面某个Button Click事件中起一个线程去做处理一些事情,在起的线程运行完毕后,接着跑Click起线程后的代码,已达到按顺序执行,保证时许正确的目的。


问题:


通常处理一个线程等待用 WaitForSingleObject,这个放在主界面线程成中会造成主界面“卡死”,其原因是它将主界面的消息循环给阻塞了,即等不到线程结束的时候界面上的消息循环无法正常工作,从而造成界面“卡死”


处理办法:


在等待线程的同时,让消息循环一直工作



示例

  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);       //按钮点亮  


Copyright Your 142132.com Rights Reserved. 赣ICP备17010829号-2