1,试验1—基础代码

1.1页面控件与代码

定时器

Timer1

Timer_work

Interval

1000

1500

Enabled

True

True

Ontimer事件

  if Timer1.Tag= then exit;  //tag=1表示正在忙

  Timer1.Tag := ;

  try

    memo1.Lines.Add(formatDatetime('NN:SS',now)+'Timer_work.tag=' + intToStr(Timer_work.tag));

  finally

    Timer1.Tag := ;

  end;
if Timer_work.Tag= then exit;  //tag=1表示正在忙

  Timer_work.Tag := ;

  try

    memo1.Lines.Add(formatDatetime('NN:SS',now)+'Timer1.tag=' + intToStr(Timer1.tag));

  finally

    Timer_work.Tag := ;

  end;

1.2运行结果与分析

39:15Timer_work.tag=0

39:16Timer1.tag=0

39:16Timer_work.tag=0

39:17Timer1.tag=0

39:17Timer_work.tag=0

39:19Timer_work.tag=0

39:19Timer1.tag=0

39:20Timer_work.tag=0

39:20Timer1.tag=0

39:21Timer_work.tag=0

39:22Timer_work.tag=0

39:22Timer1.tag=0

39:23Timer_work.tag=0

39:24Timer1.tag=0

39:24Timer_work.tag=0

39:25Timer_work.tag=0

39:25Timer1.tag=0

39:26Timer_work.tag=0

39:27Timer1.tag=0

39:27Timer_work.tag=0

39:28Timer_work.tag=0

39:28Timer1.tag=0

39:29Timer_work.tag=0

39:30Timer1.tag=0

39:30Timer_work.tag=0

39:31Timer_work.tag=0

39:31Timer1.tag=0

39:32Timer_work.tag=0

39:33Timer1.tag=0

39:33Timer_work.tag=0

以上为运行一段时间后memo1中的结果。其中:

Timer_work.tag=0出现的次数为17次

Timer1.tag=0出现的次数为12次

17/12约等于18/12=3:2=1.5:1

结果分析如下:

1,各个定时器均处于主线程中,可能是串行工作机制。即在Timer1的OnTimer事件中,Timer_work的OnTimer事件已经执行完毕,反之亦然,不会2个定时器事件同时处于执行状态。

2,2个定时器事件的执行次数比与定时器周期基本成反比。符合预期。

2,试验2—加入sleep和ProcessMessages后出现故障

2.1页面控件与代码

定时器

Timer1

Timer_work

Interval

1000

1500

Enabled

True

True

Ontimer事件

 if Timer1.Tag= then exit;  //tag=1表示正在忙

  Timer1.Tag := ;

  try

    application.ProcessMessages;

    sleep();    memo1.Lines.Add(formatDatetime('NN:SS',now)+'Timer_work.tag=' + intToStr(Timer_work.tag));

  finally

    Timer1.Tag := ;

  end;
  if Timer_work.Tag= then exit;  //tag=1表示正在忙

  Timer_work.Tag := ;

  try

    application.ProcessMessages;

    sleep();    memo1.Lines.Add(formatDatetime('NN:SS',now)+'Timer1.tag=' + intToStr(Timer1.tag));

  finally

    Timer_work.Tag := ;

  end;

2.2运行结果与分析

02:33Timer_work.tag=0

02:34Timer1.tag=0

02:35Timer_work.tag=0

02:36Timer_work.tag=1

02:37Timer_work.tag=1

02:38Timer_work.tag=1

02:39Timer_work.tag=1

02:40Timer_work.tag=1

02:41Timer_work.tag=1

02:42Timer_work.tag=1

02:43Timer_work.tag=1

02:44Timer_work.tag=1

02:45Timer_work.tag=1

02:46Timer_work.tag=1

02:47Timer_work.tag=1

02:48Timer_work.tag=1

02:49Timer_work.tag=1

02:50Timer_work.tag=1

02:51Timer_work.tag=1

02:52Timer_work.tag=1

02:53Timer_work.tag=1

02:54Timer_work.tag=1

02:55Timer_work.tag=1

02:56Timer_work.tag=1

02:57Timer_work.tag=1

02:58Timer_work.tag=1

02:59Timer_work.tag=1

03:00Timer_work.tag=1

03:01Timer_work.tag=1

以上为运行一段时间后memo1中的结果。其中:

在Timer1的OnTimer事件中,出现了Timer_work.tag=1。这说明2个定时器事件同时处于执行状态。

以上事件出现后,就一直维持每一秒输出一次Timer_work.tag=1,说明程序一直在执行Timer1的OnTimer事件,而Timer_work的OnTimer事件被抑制。

结果分析如下:

1,各个定时器均处于主线程中,可能是串行工作机制。但并不意味着“在Timer1的OnTimer事件中,Timer_work的OnTimer事件已经执行完毕”,可能从一个定时器事件中跳出去执行另一个计时器事件,也就是说2个定时器事件可能同时处于事件响应过程中,但同一时间只有1个事件正在执行。

2,本身只准备睡眠1秒的Timer_work.,经过了25秒仍未恢复执行。而timer1调用周期为1秒加上sleep 1秒,应该是每2秒输出1次“Timer_work.tag=1”,但实际输出间隔是1秒,不符合预期。

3,试验3—故障分析

3.1页面控件与代码

定时器

Timer1

Timer_work

Interval

1000

1500

Enabled

True

True

Ontimer事件

 if Timer1.Tag= then exit;  //tag=1表示正在忙

  Timer1.Tag := ;

  try

application.ProcessMessages;

memo1.Lines.Add(formatDatetime('NN:SS',now)+' in Timer1Timer before sleep' );

    sleep();    memo1.Lines.Add(formatDatetime('NN:SS',now)+'Timer_work.tag=' + intToStr(Timer_work.tag));

  finally

Timer1.Tag := ;

memo1.Lines.Add(formatDatetime('NN:SS',now)+'Timer1.tag=' + intToStr(Timer1.tag));

  end;
 if Timer_work.Tag= then exit;  //tag=1表示正在忙

  Timer_work.Tag := ;

  try

application.ProcessMessages;

    sleep();    
memo1.Lines.Add(formatDatetime('NN:SS',now)+'Timer1.tag=' + intToStr(Timer1.tag)); finally Timer_work.Tag := ; memo1.Lines.Add(formatDatetime('NN:SS',now)+'Timer_work.tag=' + intToStr(Timer_work.tag)); end;

停止按钮的响应事件:

procedure TForm1.Button1Click(Sender: TObject);

begin

  memo1.Lines.Add(formatDatetime('NN:SS',now)+' 停止按钮已按下..' );

  Timer_work.Enabled := False;

  Timer1.Enabled := False;

  memo1.Lines.Add(formatDatetime('NN:SS',now)+' 计时器已停止.' );

end;

3.2运行结果与分析

48:19 in Timer1Timer before sleep

48:20Timer_work.tag=1

48:20Timer1.tag=0

48:20 in Timer1Timer before sleep

48:21Timer_work.tag=1

48:21Timer1.tag=0

48:21 in Timer1Timer before sleep

48:22Timer_work.tag=1

48:22Timer1.tag=0

48:22 in Timer1Timer before sleep

48:23Timer_work.tag=1

48:23Timer1.tag=0

48:23 in Timer1Timer before sleep

48:24Timer_work.tag=1

48:24Timer1.tag=0

48:24 in Timer1Timer before sleep

48:25Timer_work.tag=1

48:25Timer1.tag=0

48:25 in Timer1Timer before sleep

48:26Timer_work.tag=1

48:26Timer1.tag=0

48:26 in Timer1Timer before sleep

48:27Timer_work.tag=1

48:27Timer1.tag=0

48:27 in Timer1Timer before sleep

48:28Timer_work.tag=1

48:28Timer1.tag=0

48:28 in Timer1Timer before sleep

48:29Timer_work.tag=1

48:29Timer1.tag=0

48:29 in Timer1Timer before sleep

48:30Timer_work.tag=1

48:30Timer1.tag=0

48:30 停止按钮已按下..

48:30 计时器已停止.

48:31Timer1.tag=0

48:31Timer_work.tag=0

以上为运行一段时间后memo1中的结果。其中:

在Timer1的OnTimer事件中,sleep前后相差1秒,说明时间主要被sleep函数消耗,而不是被timer的周期消耗。

Timer_work.tag=0一直到停止该计时器时才出现。

结果分析如下:

1,timer控件的周期只是调用执行的时间间隔,实际执行时间需考虑多种因素。假设timer周期为T1,timer事件响应函数执行时间为T2,那么实际执行周期为max(T1,T2),而不是T1+T2。

2,多计时器同时启用时,可能出现无法想象的结果。应避免使用application.ProcessMessages和sleep的同时调用。

4,实验总结

实验证明,以下情景可能出现问题:

  • 多个计时器函数中,至少有2个函数调用了application.ProcessMessages和 sleep中的1个或2个。

结论:

  • 为避免计时器“一睡不醒”,在计时器函数中应该谨慎调用sleep函数。

Delphi定时器控件TTimer“一睡不醒”问题研究的更多相关文章

  1. <总结>delphi WebBrowser控件的使用中出现的bug

    Delphi WebBrowser控件的使用中出现的bug:  1.WebBrowser.Visible=false:Visible属性不能使WebBrowser控件不可见,暂时用 WebBrowse ...

  2. 修改Delphi工具控件的默认字体

    修改Delphi工具控件的默认字体: 注册表: Delphi 6:    HKEY_CURRENT_USER\Software\Borland\Delphi\6.0Delphi 7:    HKEY_ ...

  3. Delphi WebBrowser控件的使用(大全 good)

    Delphi WebBrowser控件的使用 WebBrowser控件属性:1.Application      如果该对象有效,则返回掌管WebBrowser控件的应用程序实现的自动化对象(IDis ...

  4. Delphi TcxtreeList控件说明 转

    Delphi TcxtreeList控件说明   树.cxTreeList 属性: Align:布局,靠左,靠右,居中等 AlignWithMargins:带边框的布局 Anchors:停靠 (akT ...

  5. delphi按钮控件的default属性

    delphi按钮控件的default属性用于设置默认命令按钮,.设置为true时,按[Enter键]相当于用鼠标单击了该按钮 .窗口中如果有多个按钮的default是true的话,就根据tabinde ...

  6. Delphi fmx控件在手机滑动与单击的问题

    Delphi fmx控件在手机滑动与单击的问题 (2016-03-08 10:52:00) 转载▼ 标签: it delphi 分类: Delphi10 众所周知,fmx制作的app,对于象TEdit ...

  7. Delphi maskedit控件的掩码含义及用法方法

    Delphi maskedit控件的掩码含义及用法方法   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 ...

  8. Delphi StringGrid控件的用法

    Delphi StringGrid控件 组件名称:StringGrid         ●固定行及固定列:  StringGrid.FixedCols:=固定行之数;  StringGrid.Fixe ...

  9. Delphi IDHTTP控件:GET/POST 请求

    Delphi IDHTTP控件:GET/POST 请求   最近一直在使用IDHTTP,下面是一些关于 GET.POST 请求基本使用方法的代码 一.GET 请求 1 procedure GetDem ...

随机推荐

  1. stringBuffer、StringBuilder、排序、Arrays、Jdk1.5新特性(java基础知识十三)

    1.StringBuffer类的概述 * A:StringBuffer类概述 * 通过JDK提供的API,查看StringBuffer类的说明 * 1.线程安全的可变字符序列. * 2.可将字符串缓冲 ...

  2. jquery清空div里所有input输入框的值

    $("#divId input").val("");

  3. bzoj 1894 游戏

    题目大意: $n$个装备,每个装备有两个值,可以攻击该值对应的怪兽.每个装备最多用一次 每个怪兽被打一次之后就会死,每个怪兽可以被打当且仅当前面的都死了,求最多打多少个 思路: 很明显的二分图匹配,如 ...

  4. kafka实时流数据架构

    初识kafka https://www.cnblogs.com/wenBlog/p/9550039.html 简介 Kafka经常用于实时流数据架构,用于提供实时分析.本篇将会简单介绍kafka以及它 ...

  5. 1. jsp中<base target='' />标签用法

    用于页面跳转后,页面最后跳转到哪个iframe.例子如下: index.jsp :首页 <head> <base href="<%=basePath %>&qu ...

  6. HTML <legend> 标签

    转自:https://www.w3cschool.cn/htmltags/tag-legend.html <!DOCTYPE HTML> <html> <body> ...

  7. CodeForces - 55D && UVALive - 6528

    A. 问L到R有多少能被自己各个数位上的非零数字整除的数字. 关键在于dp的状态:注意到这里有三个关键属性:当前数位,2~9出现的情况(0,1不用管), 原数字取余2520的结果(2~9的最小公倍数) ...

  8. Log2Net组件代码详解(附开源代码)

    上一篇,我们介绍了Log2Net的需求和整体框架,我们接下来介绍我们是如何用代码实现Log2Net组件的功能的. 一.整体介绍 Log2Net组件本身是一个Dll,供其他系统调用. 本部分由以下几部分 ...

  9. 黑客攻防技术宝典web实战篇:查找源代码中的漏洞习题

    猫宁!!! 参考链接:http://www.ituring.com.cn/book/885 随书答案. 1. 列出 3 种可在源代码中找到明确签名的常见漏洞. (a) 跨站点脚本(b) SQL 注入( ...

  10. LuoguP1268树的重量【构造/思维】By cellur925

    题目传送门 Description 给你一个矩阵$M$,$M(i,j)$表示$i$到$j$的最短距离.定义树的重量为树上各边权之和,对于任意给出的合法矩阵$M$,已知它所能表示树的重量是唯一确定的.给 ...