MFC中的OnTimer和SetTimer


  有一段程序我調試了很久,直到今天一個偶然的靈感才想到問題的所在,事情是這樣子的:

  在MFC的View類里面有這么一段代碼:

void CMyView::OnTimer(UINT nIDEvent) 
{
CMyDoc* pDoc = GetDocument();

if(pDoc->b_ShowContour)
{
DrawDynamicContours();
}
else
{
boundaries.clear();
}
CView::OnTimer(nIDEvent);
}


void CMyView::OnInitialUpdate()
{
CView::OnInitialUpdate();
SetTimer(1,100,NULL);
}

  此段代碼的作用是用來刷新屏幕,從而達到動態顯示的效果,在此程序的另一處,有一段代碼,與之相呼應:

BOOL CImageProcessing::CheckMessageQueue()
{
MSG msg;
while(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message==WM_QUIT)
return FALSE;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return TRUE;
}

  即不斷的獲取windows的消息序列,然后執行,這樣的效果就是定時器的消息將能傳遞過去,並且得到執行。但很神奇或者說讓我很郁悶的是,居然有時候卡在消息循環里,這個問題我想了很久,並且引起win7和xp上的結果不一致。我開始以為是windows版本間的獲取消息循環的不同引起的,但后來查閱各資料,發現並非如此。今天晚上,我最初想到的是時間片輪轉不同,記得《編程之美》書上第一題,有一個sleep()環節,在設定sleep進行多長時間上,充分考慮到了系統的時間片對程序設定的影響,於是我開始懷疑是

void CMyView::OnInitialUpdate() 
{
CView::OnInitialUpdate();
SetTimer(1,100,NULL);
}

中的 SetTier(1,100,NULL),100ms時間可能跟系統時間片產生沖突,於是上網搜索windows的時間片長度,發現大部分說法都是20ms左右(后來發現我這個懷疑很可笑,但給了我另外的靈感),於是我又灰心了……

  然而,后面我卻想到,SetTimer設置的100ms時間進行刷新一次,如果在100ms之內OnTimer沒有執行完,那會不會出現資源的搶占問題?即這邊OnTimer沒有執行完,SetTimer又開始調用OnTimer(這是個神馬問題?)為了測試,我設定變量,統計了OnTimer里面的一次執行的時間,發現超過100ms的都會出現卡死的狀態,我將

SetTimer(1,100,NULL);
|修
|改
V
SetTimer(1,200,NULL);

  結果發現之前會卡死的測試用例都不會再發生了(灰常happy~~~),雖然不知道上述搶占函數是屬於個神馬問題,但起碼確定了是由上述引起的問題

  ok,解決一個大問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM