但是,在界面操作中不要使用Sleep函数,比如按钮事件中,不要调用这个函数,否则会出现意外的情况!!那么如何处理延时一段时间执行呢?使用定时器,将按钮事件中调用Sleep函数中的地方,改为启动一个一段时间执行后的定时器:SetTimer(定时器编号,毫秒数后执行,NULL);执行的动作放到定时器回调函数中执行,如果仅执行一次的,那么进到回调函数后首先将定时器关闭(即不是周期执行);
这样做的好处是,所有的“操作”(处理),都是在“本类”中。
AfxBeginThread(Fn, this);<span style="white-space:pre"> </span>//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个ns DWORD e = timeGetTime();//结束时间(毫秒级) printf("%d\n", e-s);// } }
2015_09_27编辑:在intel的x86上,还是采用“查询机器的工作频率”方式更好用:
#include <windows.h> #include <stdio.h> void main() { LARGE_INTEGER freq; LARGE_INTEGER c1, c2, c; //查询该机器本身的工作频率,并检查是否支持 BOOL b = QueryPerformanceFrequency(&freq); if(b) printf("频率 = %I64d\n", freq.QuadPart); else printf("QueryPerformanceFrequency 失败\n"); //查询该机器本身的工作频率,并检查是否支持 b = QueryPerformanceCounter(&c1); if(!b) printf("QueryPerformanceCounter 失败\n"); //下面检验Sleep(1)的精度 int i; for (i=0; i<10; i++) { QueryPerformanceCounter(&c1); c.QuadPart = c1.QuadPart - c2.QuadPart; printf("%I64d, %.5fs\n", c.QuadPart, //计数器差 c.QuadPart/(double)freq.QuadPart //周期值,单位:秒 ); c2 = c1; Sleep(1); } getchar(); }