您的位置:首页 > 其它

定时器

2016-04-21 10:26 375 查看
最近使用定时器,虽然网上例子很多,但依然费了我不少时间才把问题搞清。我要用的定时器是跟windows窗口没关系,需求是定时触发一次事件。定时器实现主要有两种方法:

1.SetTimer(m_hWnd,1,1000,func); //一个1秒触发一次的定时器。这个是给了窗口句柄,然后在窗口的消息处理函数那里处理就可以了。

2.SetTimer(NULL,1,1000,func);//这个是没有指定窗口句柄,但需要自己另加消息循环,GetMessage()等等。

当时我特别奇怪的是,第二种方式,在没有加消息循环的情况下,有的情况下用,回调函数是可以被调到的,有时又不行。后来发现,当通过窗口线程创建timer时,回调函数是可以被调到的。如果别的线程的话就不行。但是我也不需要这个消息循环,他等于会将创建timer的线程阻塞。所以我就自己写了个timer,如下:

timer.h

#include <windows.h>

class CTimer
{
typedef void(CALLBACK *Timerfunc)(void* p);
typedef Timerfunc TimerHandler;
public:
CTimer();

void Start(int time, TimerHandler func, void* lparam);

void Stop();

private:
static DWORD WINAPI ThreadProc(LPVOID p);

void Run();

private:
TimerHandler	m_handler;
int             m_interval;
void*			m_parameter;
bool			m_stopFlag;
HANDLE			m_hThread;
};

timer.cpp

#include "timer.h"

CTimer::CTimer()
{
}

void CTimer::Run()
{
unsigned long tickNow = ::GetTickCount();
unsigned long tickLastTime = tickNow;

while (!m_stopFlag)
{
tickNow = ::GetTickCount();
if (tickNow - tickLastTime > m_interval)
{
if (m_handler)
{
(*m_handler)(m_parameter);
}
tickLastTime = ::GetTickCount();
}

::Sleep(1);
}
}

void CTimer::Stop()
{
m_stopFlag = true;

if (m_hThread != INVALID_HANDLE_VALUE)
{
if (WaitForSingleObject(m_hThread, INFINITE) != WAIT_ABANDONED)
{
CloseHandle(m_hThread);
}
m_hThread = INVALID_HANDLE_VALUE;
}
}

DWORD WINAPI CTimer::ThreadProc(LPVOID p)
{
CTimer* timer = (CTimer*)p;
timer->Run();

CloseHandle(timer->m_hThread);
timer->m_hThread = INVALID_HANDLE_VALUE;

return 0;
}

void CTimer::Start(int time, TimerHandler func, void* lparam)
{
m_interval = time;
m_handler = func;
m_parameter = lparam;
m_hThread = ::CreateThread(NULL, 0, ThreadProc, this, 0, NULL);
}


使用如下:

void TimerProc(void* p)
{
<span style="white-space:pre"> </span>int a = 10;
}

CTimer* time = new CTimer();
time->Start(3000, TimerProc, this); // this就是回调函数里的参数p
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: