VC 怎样用线程来实现定时器?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC 怎样用线程来实现定时器?相关的知识,希望对你有一定的参考价值。

要实现定时刷新界面的功能。之前只是单纯设了个定时器,但是由于定时器的优先级太低,导致没有实现定时刷新的功能

参考技术A 最好不要这样做。但是可以实现:
比如线程函数这样写:
bTiming:是否开始计时;bool变量
定时间隔时间 double dbInterval = 60;//1分钟
while(bTiming)

static clock_t start = clock();
clock_t finish;
double duration;
finish = clock();
//uint:second
duration = (double)(finish - start) / CLOCKS_PER_SEC;
if (duration==dbInterval)

//定时间隔到
bTiming = false;


sleep(1);//这个必须,不然这个线程会永久占用CPU。
参考技术B 创建一个线程,再SetTimer。
这样最简单且满足你的需求,呵呵。本回答被提问者和网友采纳
参考技术C 用settimer(1,毫秒数1,NULL);和settimer(2,毫秒数2,NULL);设置2个定时器,设置不同的毫秒数.
添加WM_TIMER事件处理函数
void CTsDBDlg::OnTimer(UINT nIDEvent)

if(nIDEvent==1)
//一号定时器处理代码;
else if(nIDEvent==2)
//二号定时器处理代码;


CDialog::OnTimer(nIDEvent);

另外,虚机团上产品团购,超级便宜
参考技术D SetTimer

VC++使用SDL定时器替代Windows窗口定时器消息(附源码)

       在Windows应用程序中我们常常会使用到Windows窗口相关的定时器,去实现定时的目的。窗口定时器使用起来也确实方便,但窗口定时器在使用时有一定的缺陷,所以在某些特殊的场景下我们需要用其他类型的定时器来取代Windows窗口定时器,今天我们就来看看和Windows窗口无关的SDL定时器。

1、Windows窗口定时器介绍

       Windows窗口定时器时和窗口相关的,是运行在UI主线程中的。先调用SetTimer函数设定窗口定时器(创建定时器时会设定一个定时器id),在定时时间到了后,系统会给窗口投递一个WM_TIMER消息(消息中会携带定时器消息对应的id)。代码中收到定时器消息后,比对定时器消息对应的id,然后去执行对应的定时任务。

2、Windows窗口定时器缺陷

       Windows窗口定时器消息WM_TIMER是个优先级比较低的消息,如果当前UI线程中在频繁产生大量的消息,消息队列中有大量的消息等待处理,那么低优先级的WM_TIMER消息就会被丢弃掉,这样定时就出问题了,对应的定时任务也就无法得到执行了。

       以前听说WM_TIMER消息的优先级比较低,在大量窗口消息等待被处理时,WM_TIMER消息会被丢弃掉。对这种说法一直半信半疑,直到有次在项目中开发某个功能时遇到这样的问题,才深有体会。

       所以在窗口定时器出现问题时,我们就需要使用其他定时器了。本文我们来介绍一下SDL开源库中提供的定时器。

3、SDL开源库中提供的SDL定时器

       SDL开源库中提供的定时器是与窗口无关的,是在一个独立的线程中去计时的,是与UI线程无关的,所以即使UI线程消息再多再忙碌,SDL定时器都是比较准确的。

       SDL开源库中提供了SDL_AddTimerSDL_RemoveTimer API接口,使用起来很方便。我们通过调用SDL_AddTimer创建定时器,并设定定时器的回调函数,如下:

// 创建定时器,设定定时器回调函数
if ( m_dwSdlTimerID == 0 )

	m_dwSdlTimerID = SDL_AddTimer( 100, CbSdlTimerFunc, (void *)this );


// 定时器回调函数
static Uint32 SDLCALL CbSdlTimerFunc( Uint32 dwInterval, void *param )

    // 给目标窗口投递窗口自定义消息,告诉窗口定时器消息来了,可以执行指定的定时任务了
	CXXXXWnd* pThis = (CXXXXWnd*)param;
	::PostMessage( pThis->GetHWND(), WM_XXXXXXXXXXXX, 0, 0 );

	return dwInterval;

当定时时间到了,就会调用创建时设定的回调函数了。

       注意定时执行的任务不能直接放到回调函数中去执行,因为回调函数执行在定时器线程中的,和主线程不在同一个线程,不能将定时任务放在回调函数中执行,否则可能会导致定时器线程的堵塞。一般情况下,在回调函数中禁止执行业务代码,因为在回调函数中的执行业务代码,可能会导致回调函数所在线程的堵塞!所以,在回调函数中我们需要给主线程投递通知消息,在主线程中执行定时任务。

       在不用定时器时,调用SDL_RemoveTimer函数将定时器销毁掉,如下:

if ( m_dwSdlTimerID != 0 )

	SDL_RemoveTimer( m_dwSdlTimerID );
	m_dwSdlTimerID = 0;

4、SDL定时器库的下载

       如果要使用SDL定时器,可以去下载开源的SDL库,也可以下载此处提供的裁剪版定时器库,地址如下:

链接:https://pan.baidu.com/s/1MvR1ZYEIDaXeZyzi1E9uMg 
提取码:o1e7

以上是关于VC 怎样用线程来实现定时器?的主要内容,如果未能解决你的问题,请参考以下文章

在 VC++ 中设计定时器功能

VC++使用SDL定时器替代Windows窗口定时器消息(附源码)

帮忙用VC++6.0编写一个简易计时器。当鼠标左键单击时开始计时,鼠标右键单击时停止计时。

iOS中的定时器

C#关于定时器和多线程中对控件的操作以及界面假死的现象。

怎样取消电脑的定时关机