Delphi中的延时
从其它平台迁移而来 开发过程中经常会需要使用到延时功能,Delphi中有不少实现延时的方法,网上已有不少文章做过说明和分析,但本着实践出真知的态度,还是亲自动手研究一番心里比较踏实。 常用的延时方法 Sleep Sleep(n),延时n毫秒,延时过程中程序不响应,一般延时较小时使用。 在主线程中使用,延时较大(100+)的话会起程序假死,一般在子线程中使用较多。 无论在主线程还是子线程中,延时较长的话(如 2000 ms),一般不一次性Sleep(2000),而是分多次循环Sleep。有时为了能在延时过程中响应外部消息,还会加上Application.ProcessMessages;,如: 1 2 3 4 5 6 //延时 2000 ms for i := 0 to 19 do begin Sleep(100); Application.ProcessMessages; end; Timer Timer为定时器,用于周期性地执行某个处理。也可用来实现延时,延时过程中不会引起程序假死, GetTickCount GetTickCount返回从操作系统启动到当前所经过的毫秒数,一般用于计算代码段的用时。配合循环使用也可达到延时的功能。 1 2 3 4 n := GetTickCount; repeat Application.ProcessMessages; //若延时过程中需要响应消息可加上此句 until GetTickCount >= n + ms; //ms为延时的毫秒数 注意:使用以上代码进行延时的过程中,CPU使用率会异常地高(事实上,不加限制一直跑的循环都会导致CPU使用率过高)。 小结 以上是对Sleep、Timer和GetTickCount用于延时的简单说明,个人经验:通常较小延时的场景用Sleep,较大延时的场景用Timer,评估代码段耗时的场景用GetTickCount。至于为什么这样用,以前是不清楚的,但通过对三者的精度分析,目前已知晓来龙去脉。 延时精度分析 上文已经提到,一般用GetTickCount来分析代码段耗时,但由于本次GetTickCount在被测行列,故另寻他法。 本次测试假定系统时间是足够精确的,因此使用Now分别在延时前后获取系统当前时间来进行耗时评估。 为使测试更具代表性,每个测试点测试100次,取算术平均值。 在1ms~100ms内,测试点步长为1ms,在100ms~1000ms内,测试点步长为10ms。 为尽可能减小干扰,测试过程中未使用Application.ProcessMessages;,也未使用并行。 测试结果 XE10编译,Win10下运行,经过近5个小时的测试,结果终于出炉了。 延时(ms) Sleep GetTickCount Timer 1 1.70 15.58 15.64 2 2....