Delphi定时器控件TTimer“一睡不醒”问题研究

Delphi定时器控件TTimer“一睡不醒”问题研究,第1张

概述1,试验1—基础代码 1.1页面控件与代码 定时器 Timer1 Timer_work Interval 1000 1500 Enabled True True Ontimer事件 if Timer1.Tag=1 then exit; //tag=1表示正在忙 Timer1.Tag := 1; try memo1.Lines.Add(formatD 1,试验1—基础代码 1.1页面控件与代码

定时器

Timer1

Timer_work

Interval

1000

1500

Enabled

True

True

Ontimer事件

  if Timer1.Tag=1 then exit;  //tag=1表示正在忙   Timer1.Tag := 1;  try    memo1.lines.Add(formatDatetime(NN:SS,Now)+Timer_work.tag= + intToStr(Timer_work.tag));  finally    Timer1.Tag := 0;  end;

 

  

if Timer_work.Tag=1 then exit;  //tag=1表示正在忙  Timer_work.Tag := 1;  try    memo1.lines.Add(formatDatetime(NN:SS,Now)+Timer1.tag= + intToStr(Timer1.tag));  finally    Timer_work.Tag := 0;  end;

 

1.2运行结果与分析

 

39:15Timer_work.tag=039:16Timer1.tag=039:16Timer_work.tag=039:17Timer1.tag=039:17Timer_work.tag=039:19Timer_work.tag=039:19Timer1.tag=039:20Timer_work.tag=039:20Timer1.tag=039:21Timer_work.tag=039:22Timer_work.tag=039:22Timer1.tag=039:23Timer_work.tag=039:24Timer1.tag=039:24Timer_work.tag=039:25Timer_work.tag=039:25Timer1.tag=039:26Timer_work.tag=039:27Timer1.tag=039:27Timer_work.tag=039:28Timer_work.tag=039:28Timer1.tag=039:29Timer_work.tag=039:30Timer1.tag=039:30Timer_work.tag=039:31Timer_work.tag=039:31Timer1.tag=039:32Timer_work.tag=039:33Timer1.tag=039: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=1 then exit;  //tag=1表示正在忙   Timer1.Tag := 1;  try    application.ProcessMessages;    sleep(1000);    memo1.lines.Add(formatDatetime(NN:SS,Now)+Timer_work.tag= + intToStr(Timer_work.tag));  finally    Timer1.Tag := 0;  end;

 

  if Timer_work.Tag=1 then exit;  //tag=1表示正在忙  Timer_work.Tag := 1;  try    application.ProcessMessages;    sleep(1000);    memo1.lines.Add(formatDatetime(NN:SS,Now)+Timer1.tag= + intToStr(Timer1.tag));  finally    Timer_work.Tag := 0;  end;

 

2.2运行结果与分析
02:33Timer_work.tag=002:34Timer1.tag=002:35Timer_work.tag=002:36Timer_work.tag=102:37Timer_work.tag=102:38Timer_work.tag=102:39Timer_work.tag=102:40Timer_work.tag=102:41Timer_work.tag=102:42Timer_work.tag=102:43Timer_work.tag=102:44Timer_work.tag=102:45Timer_work.tag=102:46Timer_work.tag=102:47Timer_work.tag=102:48Timer_work.tag=102:49Timer_work.tag=102:50Timer_work.tag=102:51Timer_work.tag=102:52Timer_work.tag=102:53Timer_work.tag=102:54Timer_work.tag=102:55Timer_work.tag=102:56Timer_work.tag=102:57Timer_work.tag=102:58Timer_work.tag=102:59Timer_work.tag=103:00Timer_work.tag=103: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=1 then exit;  //tag=1表示正在忙   Timer1.Tag := 1;  tryapplication.ProcessMessages;memo1.lines.Add(formatDatetime(NN:SS,Now)+ in Timer1Timer before sleep );    sleep(1000);    memo1.lines.Add(formatDatetime(NN:SS,Now)+Timer_work.tag= + intToStr(Timer_work.tag));  finallyTimer1.Tag := 0;memo1.lines.Add(formatDatetime(NN:SS,Now)+Timer1.tag= + intToStr(Timer1.tag));  end;

 

 

 if Timer_work.Tag=1 then exit;  //tag=1表示正在忙  Timer_work.Tag := 1;  tryapplication.ProcessMessages;     sleep(1000);    
memo1.lines.Add(formatDatetime(NN:SS,Now)+Timer1.tag= + intToStr(Timer1.tag)); finallyTimer_work.Tag := 0;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 sleep48:20Timer_work.tag=148:20Timer1.tag=048:20 in Timer1Timer before sleep48:21Timer_work.tag=148:21Timer1.tag=048:21 in Timer1Timer before sleep48:22Timer_work.tag=148:22Timer1.tag=048:22 in Timer1Timer before sleep48:23Timer_work.tag=148:23Timer1.tag=048:23 in Timer1Timer before sleep48:24Timer_work.tag=148:24Timer1.tag=048:24 in Timer1Timer before sleep48:25Timer_work.tag=148:25Timer1.tag=048:25 in Timer1Timer before sleep48:26Timer_work.tag=148:26Timer1.tag=048:26 in Timer1Timer before sleep48:27Timer_work.tag=148:27Timer1.tag=048:27 in Timer1Timer before sleep48:28Timer_work.tag=148:28Timer1.tag=048:28 in Timer1Timer before sleep48:29Timer_work.tag=148:29Timer1.tag=048:29 in Timer1Timer before sleep48:30Timer_work.tag=148:30Timer1.tag=048:30 停止按钮已按下..48:30 计时器已停止.48:31Timer1.tag=048: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“一睡不醒”问题研究全部内容,希望文章能够帮你解决Delphi定时器控件TTimer“一睡不醒”问题研究所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1265391.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存