介绍(java)
Timer 是一个使用回调方法的计时器,而且由线程池线程服务,简单且对资源要求不高。请使用 Dispose 方法释放计时器持有的资源。
使用 TimerCallback 委托指定希望 Timer 执行的方法。计时器委托在构造计时器时指定,并且不能更改。此方法不在创建计时器的线程中执行,而是在系统提供的线程池线程中执行。
创建计时器时,可以指定在第一次执行方法之前等待的时间量(截止时间)以及此后的执行期间等待的时间量(时间周期)。
Timer的构造函数:
Timer(Callback, State, dueTime, Period);
【参数】
- Callback:一个 TimerCallback 委托,表示要执行的方法;
- State:一个包含回调方法要使用的信息的对象,或者为空;
- dueTime:调用 callback 之前延迟的时间量(以毫秒为单位)。指定 Timeout.Infinite 以防止计时器开始计时,指定零 (0) 以立即启动计时器;
- Period:调用 callback 的时间间隔(以毫秒为单位)。指定 Timeout.Infinite 可以禁用定期终止;
简单示例:
Timer timerClose;
imerClose = new Timer(new TimerCallback(timerCall), this, 5000, 0);
使用SetTimer设置定时器(C++)
SetTimer
函数原型:
UINT_PTR SetTimer
(
HWND hWnd, // 窗口句柄,通常可以省去
UINT_PTR nIDEvent, //定时器ID,多个定时器时可以通过该ID判断是哪个定时器
UINT uElapse, // 时间间隔,单位为毫秒
TIMERPROC lpTimerFunc // 回调函数
);
例如:
SetTimer(1,1000,NULL); //一个1秒触发一次的定时器
【返回值】
就是第一个参数值1,表示此定时器的ID号。;
【参数】
第二个参数表示要等待1000毫秒时间再重新处理一次;
第三个参数在这种方法中一般用NULL;
注意:设置第二个参数时要注意,如果设置的等待时间比处理时间短,程序就会出问题了。
回调函数
示例:
void CALLBACK TimerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime);
然后再用SetTimer(1,100,TimerProc)函数来建一个定时器,第三个参数就是回调函数地址。
回调函数的设置参考:
TimerCallback<StatTimer> callback;
【说明】
- TimerCallback:标志这是一个定义回调函数的格式;
- StatTimer:回调函数所在的类class,即入口函数所在的对象;
- callback:回调函数格式的实例 如callback(StatTimer,&StatTimer::onTimer),StatTimer是调用改定时器的类,onTimer为该类中的方法,即该定时器的入口函数;
多个定时器
设置定时器时为其指定了ID,使用多个定时器时,该ID就发挥作用了。
不使用MFC时,当接收到WM_TIMER,WPARAM wParam中的值便是该定时器的ID 。
使用MFC时就更简单了,我们为其增加WM_TIME的消息处理函数OnTimer即可,示例:
void CTimerTestDlg::OnTimer(UINT nIDEvent)
{
switch (nIDEvent)
{
case 24: ///处理ID为24的定时器
Draw1();
break;
case 25: ///处理ID为25的定时器
Draw2();
break;
}
CDialog::OnTimer(nIDEvent);
}
##KillTimer 取消定时器
函数原型:
BOOL KillTimer(
HWND hWnd, // 窗口句柄,通常可以省去
UINT_PTR uIDEvent // ID
);
##获取高精度计时器
涉及函数:
QueryPerformanceFrequency()和QueryPerformanceCounter()
要求计算机从硬件上支持高精度定时器,需包含windows.h头文件。
【函数原型】
BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
BOOL QueryPerformanceCounter (LARGE_INTEGER *lpCount);
数据类型LARGEINTEGER既可以是一个作为8字节长的整数,也可以是作为两个4字节长的整数的联合结构,其具体用法根据编译器是否支持64位而定。该类型的定义如下:
typeef union _ LARGE_INTEGER
{
struct
{
DWORD LowPart;
LONG HighPart;
};
LONGLONG QuadPart;
} LARGE_INTEGER;
【示例】
在定时前应该先调用QueryPerformanceFrequency()函数获得机器内部计时器的时钟频率。接着在需要严格计时的事件发生前和发生之后分别调用QueryPerformanceCounter(),利用两次获得的计数之差和时钟频率,就可以计算出事件经历的精确时间。
#include <stdio.h>
#include <windows.h>
void main()
{
LARGE_INTEGER nFreq;
LARGE_INTEGER nBeginTime;
LARGE_INTEGER nEndTime;
double time;
QueryPerformanceFrequency(&nFreq);
QueryPerformanceCounter(&nBeginTime);
Sleep(1000);
QueryPerformanceCounter(&nEndTime);
time=(double)(nEndTime.QuadPart-nBeginTime.QuadPart)/(double)nFreq.QuadPart;
printf("%f\n",time);
Sleep(1000);
system("Pause");
}
结果为
0.999982
1.000088
1.000200
等,所以Sleep的精度还是比较低的。
读后有收获可以支付宝请作者喝咖啡: