[讨论]关于TTimer控件的使用

时间:2022-04-04 20:36:34
我在程序开发中,如果有需要用到时间的操作时,想都不想,我就使用TTimer控件了。但是现在程序有时候会出现白屏的情况,而我看了进程,程序好象并没有死掉,只是在执行什么操作(因为程序底层不是我写的,我现在也不清楚这时候程序在执行什么操作)。

大家进来讨论一下关于TTimer的一些利和弊吧

31 个解决方案

#1


结帖率:101.08%
这个怎么算出来的
ps:我也是用timer  还没发现弊

#2


引用 1 楼 xiaofansong 的回复:
结帖率:101.08%
这个怎么算出来的
ps:我也是用timer 还没发现弊

 MD,被某位版猪没有理由删了我一个贴子,结果就变成这样了

#3


计数器就是对于一段时间就会重复的过程,例如windows xp 有个自动升级的应用,就是在固定时间的时候发生某个动作

#4


感觉Delphi自带的Timer貌似计时不是很精确

而且,感觉是要把Timer里边的代码执行完了才开始下一个周期的。。。

#5


Timer控件的设置和使用都非常方便,理论上它的记时精度可以达到1ms。

但实际上Timer在记时间隔小于50ms之下是精度是十分差的。所以不适用于对于精度要求太高的场合。

“出现白屏”这种情况大概是其他代码没处理好。

#6


引用 5 楼 keeley20 的回复:
Timer控件的设置和使用都非常方便,理论上它的记时精度可以达到1ms。

但实际上Timer在记时间隔小于50ms之下是精度是十分差的。所以不适用于对于精度要求太高的场合。

“出现白屏”这种情况大概是其他代码没处理好。

我现在有时候出现白屏的情况后,如果把电脑重启一下后就不会出现这种情况,所以很郁闷的

#7


引用 4 楼 hongss 的回复:
感觉Delphi自带的Timer貌似计时不是很精确

而且,感觉是要把Timer里边的代码执行完了才开始下一个周期的。。。

本来就是的啊,你里面的代码不执行完怎么能再从头开始执行呢

#8


Timer在一般的情况下还是可以处理,但如果是多线程的处理建议最好不要用Timer的东东。

#9


处理量少才用TIMER

#10


引用 2 楼 winstonbonaparte 的回复:
引用 1 楼 xiaofansong 的回复:
结帖率:101.08%
这个怎么算出来的
ps:我也是用timer 还没发现弊

 MD,被某位版猪没有理由删了我一个贴子,结果就变成这样了


MD,估计你的帖子违反版规了

#11


引用 10 楼 hongqi162 的回复:
引用 2 楼 winstonbonaparte 的回复:
引用 1 楼 xiaofansong 的回复:
结帖率:101.08%
这个怎么算出来的
ps:我也是用timer 还没发现弊

MD,被某位版猪没有理由删了我一个贴子,结果就变成这样了


MD,估计你的帖子违反版规了

......我就引用了*的一句話,就被刪了。。。。。。

#12


引用回复
而且,感觉是要把Timer里边的代码执行完了才开始下一个周期的。。。
本来就是的啊,你里面的代码不执行完怎么能再从头开始执行呢

通常情况是这样.

有一种例外情况,如果Timer执行过程中执行了这句Applicarion.ProcessMessages,那Timer可能再次触发,消息响应就是这样的

以下过程Timer1.Interval = 1000

procedure TForm1.Timer1Timer(Sender: TObject);
var
  i : integer;
begin
  Application.MessageBox('Timer被执行了' , '提示' , 64);
  for i:=0 to 100 do begin
    Sleep(100);
    Application.ProcessMessages;
  end;
end;

你可以看到点了第一个之后,将跳出多个对话框出来

#13


引用 12 楼 kiboisme 的回复:
引用回复
而且,感觉是要把Timer里边的代码执行完了才开始下一个周期的。。。
本来就是的啊,你里面的代码不执行完怎么能再从头开始执行呢

通常情况是这样.

有一种例外情况,如果Timer执行过程中执行了这句Applicarion.ProcessMessages,那Timer可能再次触发,消息响应就是这样的

以下过程Timer1.Interval = 1000

proc……

那如果我在执行一个比较耗时,比如说要十几秒的TTimer时,我要怎么能让它响应程序呢

#14


引用 13 楼 winstonbonaparte 的回复:
那如果我在执行一个比较耗时,比如说要十几秒的TTimer时,我要怎么能让它响应程序呢


计时器用TTimer,触发后用多线程执行相关操作

#15


引用 14 楼 sparklerl 的回复:
计时器用TTimer,触发后用多线程执行相关操作

这个方法不错,有时候也可以选择以下方法



implementation

var
  pbRuning : Boolean;     //控制执行变量,也可以放到TForm1类里的Private里定义

procedure TForm1.Timer1Timer(Sender: TObject);
var
  i : integer;
begin
  Timer1.Enabled := False;        //让Timer1不再执行
  StartBtn.Enabled := False;      //让其他不想让用户中断的操作执行
  StopBtn.Caption := '停止';
  StopBtn.Enabled := True;
  pbRuning := True;

  for i:=0 to 1000 do begin     //正常情况这里需要大约100秒才能执行完
    Sleep(100);                 //这里相当于你的其他代码所消耗的时钟
    Application.ProcessMessages;
    if not pbRuning then begin
      Application.MessageBox('用户取消' , '提示' , 64);
      Break;
    end;
  end;
  StartBtn.Enabled := True;      //恢复 用户操作
  StopBtn.Enabled := False;
  Timer1.Enabled := True;        //让Timer1继续
end;

//如果循环量非常大,那么每次循环都执行Application.ProcessMessages;也不经济,可以考虑加上
//if (i mod 100)=0 then Application.ProcessMessages;

procedure TForm1.StopBtnClick(Sender: TObject);
begin
  pbRuning := False;
end;



以上是针对多次循环的情况,如果是
AdoQuery1.Open;     //这里由于网络,服务器压力,所取数据多少等关系,消耗大量的时间的情况,则不适用以上代码,

具体情况得根据要完成的工作来选择相应的处理

#16


嗯,我覺得如果要取大數據量的時候還是不要用時鐘的好,用線程比較好

#17


ttimer启动时好像会有个停顿

#18


引用 15 楼 kiboisme 的回复:
引用 14 楼 sparklerl 的回复:
计时器用TTimer,触发后用多线程执行相关操作

这个方法不错,有时候也可以选择以下方法


Delphi(Pascal) code


implementation

var
  pbRuning : Boolean;     //控制执行变量,也可以放到TForm1类里的Private里定义

procedure TF……
  

可以用win_closs关掉了从开。

#19


应该不是ttimer控件的问题,注意一下,把ttimer的时间设知一点,看会有什么情况,是不是问题更严重,如果是,应该是ttimer里面执行的代码有问题

#20


消息循环里只会有一个timer,如果一个没有执行完,另一个即便被触发,也会自动丢弃的。

#21


Timer里的事件处理应该是时间很短或者可以放弃的那种。

#22


用线程吧,这样也不占资源!!!

#23


1、timer运行始终占用CPU和内存。
2、timer计时不能与Now同步。

#24


结帖率:101.08%
这个怎么算出来的

高级

Timer数量不要太多

#25


Timer数量太多了,101。8的牛人

#26


TImer在时间短的情况下,会连续多次触发!
所以如果间隔很短,搞一个标记,进入的时候,先判断标记,如果标记正在运行,直接推出,不管,然后标记状态为运行,在运行完成之后,标记为运行完成!

#27


要求高的话用线程代替或者用多媒体定时器
TimeSetEvent

#28


Timer与多线程相比

利:
不需要考虑同步

弊:
如果操作时间很长,主界面会冻结
wm_timer在消息队列中只会存一份,多次触发,可能只执行一次

#29


应该是代码太多,或者一直在执行VCL控件的相关操作.

#30


没编过复杂的,最多用一个,不过记号学习一下

#31


Timer重要的是Active。查一查这一块

#1


结帖率:101.08%
这个怎么算出来的
ps:我也是用timer  还没发现弊

#2


引用 1 楼 xiaofansong 的回复:
结帖率:101.08%
这个怎么算出来的
ps:我也是用timer 还没发现弊

 MD,被某位版猪没有理由删了我一个贴子,结果就变成这样了

#3


计数器就是对于一段时间就会重复的过程,例如windows xp 有个自动升级的应用,就是在固定时间的时候发生某个动作

#4


感觉Delphi自带的Timer貌似计时不是很精确

而且,感觉是要把Timer里边的代码执行完了才开始下一个周期的。。。

#5


Timer控件的设置和使用都非常方便,理论上它的记时精度可以达到1ms。

但实际上Timer在记时间隔小于50ms之下是精度是十分差的。所以不适用于对于精度要求太高的场合。

“出现白屏”这种情况大概是其他代码没处理好。

#6


引用 5 楼 keeley20 的回复:
Timer控件的设置和使用都非常方便,理论上它的记时精度可以达到1ms。

但实际上Timer在记时间隔小于50ms之下是精度是十分差的。所以不适用于对于精度要求太高的场合。

“出现白屏”这种情况大概是其他代码没处理好。

我现在有时候出现白屏的情况后,如果把电脑重启一下后就不会出现这种情况,所以很郁闷的

#7


引用 4 楼 hongss 的回复:
感觉Delphi自带的Timer貌似计时不是很精确

而且,感觉是要把Timer里边的代码执行完了才开始下一个周期的。。。

本来就是的啊,你里面的代码不执行完怎么能再从头开始执行呢

#8


Timer在一般的情况下还是可以处理,但如果是多线程的处理建议最好不要用Timer的东东。

#9


处理量少才用TIMER

#10


引用 2 楼 winstonbonaparte 的回复:
引用 1 楼 xiaofansong 的回复:
结帖率:101.08%
这个怎么算出来的
ps:我也是用timer 还没发现弊

 MD,被某位版猪没有理由删了我一个贴子,结果就变成这样了


MD,估计你的帖子违反版规了

#11


引用 10 楼 hongqi162 的回复:
引用 2 楼 winstonbonaparte 的回复:
引用 1 楼 xiaofansong 的回复:
结帖率:101.08%
这个怎么算出来的
ps:我也是用timer 还没发现弊

MD,被某位版猪没有理由删了我一个贴子,结果就变成这样了


MD,估计你的帖子违反版规了

......我就引用了*的一句話,就被刪了。。。。。。

#12


引用回复
而且,感觉是要把Timer里边的代码执行完了才开始下一个周期的。。。
本来就是的啊,你里面的代码不执行完怎么能再从头开始执行呢

通常情况是这样.

有一种例外情况,如果Timer执行过程中执行了这句Applicarion.ProcessMessages,那Timer可能再次触发,消息响应就是这样的

以下过程Timer1.Interval = 1000

procedure TForm1.Timer1Timer(Sender: TObject);
var
  i : integer;
begin
  Application.MessageBox('Timer被执行了' , '提示' , 64);
  for i:=0 to 100 do begin
    Sleep(100);
    Application.ProcessMessages;
  end;
end;

你可以看到点了第一个之后,将跳出多个对话框出来

#13


引用 12 楼 kiboisme 的回复:
引用回复
而且,感觉是要把Timer里边的代码执行完了才开始下一个周期的。。。
本来就是的啊,你里面的代码不执行完怎么能再从头开始执行呢

通常情况是这样.

有一种例外情况,如果Timer执行过程中执行了这句Applicarion.ProcessMessages,那Timer可能再次触发,消息响应就是这样的

以下过程Timer1.Interval = 1000

proc……

那如果我在执行一个比较耗时,比如说要十几秒的TTimer时,我要怎么能让它响应程序呢

#14


引用 13 楼 winstonbonaparte 的回复:
那如果我在执行一个比较耗时,比如说要十几秒的TTimer时,我要怎么能让它响应程序呢


计时器用TTimer,触发后用多线程执行相关操作

#15


引用 14 楼 sparklerl 的回复:
计时器用TTimer,触发后用多线程执行相关操作

这个方法不错,有时候也可以选择以下方法



implementation

var
  pbRuning : Boolean;     //控制执行变量,也可以放到TForm1类里的Private里定义

procedure TForm1.Timer1Timer(Sender: TObject);
var
  i : integer;
begin
  Timer1.Enabled := False;        //让Timer1不再执行
  StartBtn.Enabled := False;      //让其他不想让用户中断的操作执行
  StopBtn.Caption := '停止';
  StopBtn.Enabled := True;
  pbRuning := True;

  for i:=0 to 1000 do begin     //正常情况这里需要大约100秒才能执行完
    Sleep(100);                 //这里相当于你的其他代码所消耗的时钟
    Application.ProcessMessages;
    if not pbRuning then begin
      Application.MessageBox('用户取消' , '提示' , 64);
      Break;
    end;
  end;
  StartBtn.Enabled := True;      //恢复 用户操作
  StopBtn.Enabled := False;
  Timer1.Enabled := True;        //让Timer1继续
end;

//如果循环量非常大,那么每次循环都执行Application.ProcessMessages;也不经济,可以考虑加上
//if (i mod 100)=0 then Application.ProcessMessages;

procedure TForm1.StopBtnClick(Sender: TObject);
begin
  pbRuning := False;
end;



以上是针对多次循环的情况,如果是
AdoQuery1.Open;     //这里由于网络,服务器压力,所取数据多少等关系,消耗大量的时间的情况,则不适用以上代码,

具体情况得根据要完成的工作来选择相应的处理

#16


嗯,我覺得如果要取大數據量的時候還是不要用時鐘的好,用線程比較好

#17


ttimer启动时好像会有个停顿

#18


引用 15 楼 kiboisme 的回复:
引用 14 楼 sparklerl 的回复:
计时器用TTimer,触发后用多线程执行相关操作

这个方法不错,有时候也可以选择以下方法


Delphi(Pascal) code


implementation

var
  pbRuning : Boolean;     //控制执行变量,也可以放到TForm1类里的Private里定义

procedure TF……
  

可以用win_closs关掉了从开。

#19


应该不是ttimer控件的问题,注意一下,把ttimer的时间设知一点,看会有什么情况,是不是问题更严重,如果是,应该是ttimer里面执行的代码有问题

#20


消息循环里只会有一个timer,如果一个没有执行完,另一个即便被触发,也会自动丢弃的。

#21


Timer里的事件处理应该是时间很短或者可以放弃的那种。

#22


用线程吧,这样也不占资源!!!

#23


1、timer运行始终占用CPU和内存。
2、timer计时不能与Now同步。

#24


结帖率:101.08%
这个怎么算出来的

高级

Timer数量不要太多

#25


Timer数量太多了,101。8的牛人

#26


TImer在时间短的情况下,会连续多次触发!
所以如果间隔很短,搞一个标记,进入的时候,先判断标记,如果标记正在运行,直接推出,不管,然后标记状态为运行,在运行完成之后,标记为运行完成!

#27


要求高的话用线程代替或者用多媒体定时器
TimeSetEvent

#28


Timer与多线程相比

利:
不需要考虑同步

弊:
如果操作时间很长,主界面会冻结
wm_timer在消息队列中只会存一份,多次触发,可能只执行一次

#29


应该是代码太多,或者一直在执行VCL控件的相关操作.

#30


没编过复杂的,最多用一个,不过记号学习一下

#31


Timer重要的是Active。查一查这一块

相关文章