Delphi中的计时器
考虑以下代码Delphi中的计时器,delphi,Delphi,考虑以下代码 Timer1 .Enabled := False; Timer1.Interval : = 300; For I := 1 to NumberOfTimesNeed do Begin Timer1 .Enabled := False; // Timer1 .Enabled := True; // reset the timer to 0.30 seconds TakesToLong := False; DoSomethingTh
Timer1 .Enabled := False;
Timer1.Interval : = 300;
For I := 1 to NumberOfTimesNeed do
Begin
Timer1 .Enabled := False; //
Timer1 .Enabled := True; // reset the timer to 0.30 seconds
TakesToLong := False;
DoSomethingThatTakesTime; // Application.ProcessMessages is called in the procedure
If TakesToLong = True then
TakeAction;
End;
procedure Timer1Timer(Sender: TObject);
begin
TakesToLong:= True;
end;
问题:
当我禁用然后启用计时器1时
Timer1.Enabled := False;
Timer1.Enabled := True;
这会重置计时器吗
i、 e.在超时前,它将始终等待0.30秒 是的,会的。如果之前启用了计时器,则将Enabled设置为False将调用Windows API函数KillTimer()。如果之前未启用计时器,则将Enabled设置为True将调用Windows API函数SetTimer() 这是一个标准的习惯用法,从Delphi1时代起就一直有效 但是,我将以不同的方式实现您的代码:
Start := GetSystemTicks;
DoSomethingThatTakesTime;
Duration := GetSystemTicks - Start;
if Duration > 300 then
TakeAction;
这将在没有计时器的情况下工作,并且不需要在long taking方法中调用ProcessMessages()。GetSystemTicks()是我在库中拥有的一个函数,它在Windows中调用timeGetTime(),对于Kylix它的实现方式不同(不记得我很久以前是如何清除该代码的)。我建议阅读线程。长时间的操作(我不是说300毫秒很长,但听起来很明显,它可能会比这更长)会冻结GUI并导致应用程序不稳定。现在,您可以在其中抛出application.processmessages来保持GUI的运行,但它可以很容易地摆脱您预期的过程编码风格 我来自相信应用程序的那一边。ProcessMessages应该被禁止,除非你是一个试图使用Delphi模仿DoEvents的VB程序员,而且你还没有摆脱VB思维模式
生成一个线程并在该线程中执行您的工作。如果要在完成时更新GUI端,请调用Synchronize以“安全地”进行更新。与线程来回通信正在进行的状态会带来一个全新的对话,这与使用计时器控件相比是一个很大的飞跃。需要注意的另一件事是,计时器是系统上优先级最低的通知。因此,如果计算机正忙,其中可能包括正在工作的应用程序,计时器可能在相当长的一段时间内不会触发。因此,TakesToLong变量设置为true可能需要几秒钟,即使计时器设置为300毫秒。答案很好,建议也更好@MGHIE我已经改变了代码使用GETSealTICKS,它工作得很好,谢谢:)或者,考虑使用A。有一次,然后在每次循环迭代中,您可以执行您的工作(不必担心消息处理),最后使用
WaitForSingleObject()
以0毫秒的超时来查看计时器是否已过。呃,您为什么不试试呢?没有0.3秒的空闲时间?;)虽然我认为线程是一件伟大的事情,但使用它们同样会“摆脱您预期的过程编码风格”(顺便说一句,我同意这一观点,我只是指出它)。GUI必须以相同的方式处理,以防止调用不可重入代码。事实上,如果窗口消息队列为非空,则计时器消息永远不会明显“接收”,因此基本上计算机只需做一些轻微的处理工作,计时器消息可能会离开一段不确定的长时间(在我的一些应用程序中,我已经看到这种情况发生了好几个小时。)