VC中的Sleep函數在延時應用中很好用,比如通訊程式中,一方需等待另一方若干個毫秒後再處理,或者在死迴圈中,讓出CPU不至於資源佔用100%等等;
但是,在介面操作中不要使用Sleep函數,比如按鈕事件中,不要調用這個函數,否則會出現意外的情況!!那麼如何處理延時一段時間執行呢?使用定時器,將按鈕事件中調用Sleep函數中的地方,改為啟動一個一段時間執行後的定時器:SetTimer(定時器編號,毫秒數後執行,NULL);執行的動作放到定時器回呼函數中執行,如果僅執行一次的,那麼進到回呼函數後首先將定時器關閉(即不是周期執行);
這樣做的好處是,所有的“操作”(處理),都是在“本類”中。
另一個方案是啟動一個線程:AfxBeginThread(處理回呼函數,傳遞給回呼函數的參數);但是也不建議使用!!因為,一般使用該函數都是這樣使用,調用時:
AfxBeginThread(Fn, this);//this是“目前正在處理這個類”的指標
而在回呼函數Fn中一般:
UINT Fn( LPVOID pParam ){CMyDlg *pDlg = (CMyDlg *)pParam;//切換到“正在處理”的類中//其他處理return 1L;}
這涉及到RTTI,微軟MFC在這方面做得不是太好(我在使用codeproject上的一些衍生類別控制項就遇到了幾個不解的問題,不知道是微軟MFC的問題,還是那些衍生類別控制項的問題),保守一點,使用定時器,可以避免這方面的彎路!
2. Sleep()的精度是可以保證的,如Sleep(4),能保證延時4個毫秒,但是不能用GetTickCOunt()函數來探測(最小精度15毫秒,不信自己驗證),而是需使用:
#include <windows.h>#include <stdio.h>//連結庫#pragma comment(lib, "Winmm.lib")void main(){timeBeginPeriod(1);Sleep(100);int j=0;//探測10次Sleep的延時for(int i=0; i<10; i++){DWORD s = timeGetTime();//開始時間(毫秒級)//延時函數Sleep(2);//for (j=0; j<10000000; j++);//測算34~40毫秒,所以for迴圈每條指令為3~4個nsDWORD e = timeGetTime();//結束時間(毫秒級)printf("%d\n", e-s);//}}