当前位置:C++技术网 > 精选软件 > 计时器的使用经验总结:1 时间显示和计时(正向计时和倒计时)以及周期触发

计时器的使用经验总结:1 时间显示和计时(正向计时和倒计时)以及周期触发

更新时间:2016-06-03 19:46:45浏览次数:1+次

    计时器的使用,可以说是非常常见的了。但是大部分人也都只用计时器计时和做周期性的事情了。然而,计时应用是最基本的,知道计时器的应该都会使用计时器。
    我们这里不探讨计时器本身的使用,而是探讨一下计时器应用的经验。
    计时器就是定时的激发一个事情。可以这么理解,所有周期性的事情,都可以用计时器来做。当然,与周期性相关延伸的,也可以用计时器做。下面我来仔细说说。
    周期性,我想大家都非常熟悉了。最常见的就是时间计时。其实有些经验不足的,还不能很好的使用计时器。我们先从简单的做法说起。
    我们要实现计时,很直接想到的就是计时器周期性的运行,那么我们可以用计时器数秒,就可以实现钟表的效果。假如你知道现在的时间时2016年6月3日19:17:52,然后你开始数秒,下一秒为2016年6月3日19:17:53,再下一秒为2016年6月3日19:17:54。两个不同的时间就相隔一秒,所以这个和计时器的周期性激发一个动作一致,所以计时器可以数秒。你可以在启动计时器的时候,获取系统的时间,比如就是2016年6月3日19:17:52,然后用一个变量计数,计时器每一次触发,也就是要执行计时器函数的时候,你就在这个函数里将这个变量加1,然后将这个时间加到最开始获取到的系统时间里。这样就实现了数秒。然后再显示相加后的时间,就得到了当前的时间。
    看上去很不错。这种实现方法,和计时器的特性一致。本来是没有问题的,然而当你了解了计时器的工作环境,你就会发现这样的方法,不能准确的显示时间,当然也不能用来计时。我们说的显示时间,就是不停更新显示当前的时间,而计时分为正向计时和倒计时,计时就是简单的数字以计时器间隔周期来累计数值而已。显示时间则还要与之前得到的实现相加。
    如果说这样显示时间的方式得到的时间并不准确,你能想到是什么问题吗?
    实际上,这个和你实现的思路没有任何关系,问题出在计时器本身。如果计时器本身能够保证严格的周期性触发时间,执行计时器函数的话,上面的方法完全OK。但是在Windows中,计时器当做一个窗口消息被发送到窗口的消息队列,而且,计时器消息的优先级是很低的,这样的话,在窗口消息不多的情形下,计时器消息能够及时处理,这样计时还是可以准确的。当消息变多的时候,计时器消息就不能处理及时了。这样虽然计时器每隔一个周期向窗口消息队列发送了一个计时器消息,然而要触发计时器事件,实际上就是计时器消息被处理,也就是调用了计时器消息,也就是执行了你写的计时器消息处理代码。
    正是因为计时器消息不能确保都能够及时处理,所以,有时候可以堆积好几个计时器消息,然后界面上看到的时间不动了,然后缓过来的时候,几个计时器消息连续被处理,时间一下子刷刷的跳动了几下。这样的计时效果,谁也不能接受的。这样时间的准确度也绝对无法保证。不管是显示时间,还是计时(正向计时和倒计时),都不一定总是准确的。这也是为什么很多人说计时器计时不准确的原因。问题不是计时器间隔产生的时间不准确,而是处理的间隔无法保障。当你的机器有一种机制,可以以准确的间隔周期来执行一个动作,那么你的计时就可以准确了。我敢肯定,很多人在这一点上都理解偏差了。
    所以,在这样的情况下,就算你的时间再精确,只要不能在准确的间隔时间被处理,也是没有用的。
    我们要么找到一种可以直接获取准确间隔触发的计时器。这是一种方案。我想应该是有的。我们计算机的时钟是准确的,只是Windows将计时器得到的精确的计时转变成计时器消息传给我们处理,才让我们无法利用准确的计时了。
    在计时方面,计算机一般的时钟就完全可以满足了。当然,在更专业的计时里,单位更加微小,不再是以秒为单位,比如以微妙为单位,以纳秒为单位,那么此时瓶颈就在于时钟的精度上了。一般情况下,这个根本不是考虑的。我们日常时间的时间计时,不需要,我们有秒级微妙级的完全足够了。这里很多人都误以为大家常说的计时器计时不准确,以为是计算机时钟不准确。希望看了本文能够矫正过来。
    前面的方案就是直接得到计算机时钟的间隔,在这个间隔时间触发计时器消息,这样我们处理的时间间隔是可以保证的,这样绕过窗口消息的计时器机制。但是这样的方法,似乎不太好搞,反正我现在也不知道。如果你知道,请告诉我一下。
    然而我还是做了很多计时的应用。第一种方案似乎比较麻烦。我们利用了计时器的间隔,却被消息处理不及时而浪费了。但是另一种方法还是可以准确计时的。
    我们知道,我们随时获取的系统时间都是准确的。那么我们在计时器触发的时候,每次只是获取当时的系统时间,然后显示出来,这样不就是准确的嘛。就算计时器消息被延迟了,但是不管什么时候更新的时间,时间总是准确的。只是在界面上看起来,某一个时段时间被卡住了而已。但是它更新了,就是准确的。
    这一个方案,应用在时间显示和计时上都是准确的。特别是计时,大家都很喜欢用变量计数的方式来计时,实际上这样是不准确的。同样,计时也得和显示时间一样,每次都获取当时的时间,然后减去开始的时间,计算时间间隔,这样得到的时间是准确的。
    有了第二个方案,基本上日常的计时应用都搞定了。
    当然,计时显示时间只是很小的一个应用罢了。在利用周期性的特性中,我们还可以利用计时器间隔触发,来完成很多定期提醒的功能。这样的功能就太多了。我们可以实现定期触发一件事情,也可以定期检查一个状态,而不只是时间哦。不过处理方法和时间显示以及计时差不多,就不多讲了。
    后面讲讲述计时器的另外一个应用,即超时检测方面的问题。