通常情况是这样.有一种例外情况,如果Timer执行过程中执行了这句Applicarion.ProcessMessages,那Timer可能再次触发,消息响应就是这样的以下过程Timer1.Interval = 1000procedure 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;你可以看到点了第一个之后,将跳出多个对话框出来
那如果我在执行一个比较耗时,比如说要十几秒的TTimer时,我要怎么能让它响应程序呢
计时器用TTimer,触发后用多线程执行相关操作
这个方法不错,有时候也可以选择以下方法implementationvar 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; //这里由于网络,服务器压力,所取数据多少等关系,消耗大量的时间的情况,则不适用以上代码,具体情况得根据要完成的工作来选择相应的处理
这个怎么算出来的
ps:我也是用timer 还没发现弊
var
i : integer;
begin
Application.MessageBox('Timer被执行了' , '提示' , 64);
for i:=0 to 100 do begin
Sleep(100);
Application.ProcessMessages;
end;
end;你可以看到点了第一个之后,将跳出多个对话框出来
计时器用TTimer,触发后用多线程执行相关操作
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; //这里由于网络,服务器压力,所取数据多少等关系,消耗大量的时间的情况,则不适用以上代码,具体情况得根据要完成的工作来选择相应的处理
2、timer计时不能与Now同步。
这个怎么算出来的高级Timer数量不要太多
所以如果间隔很短,搞一个标记,进入的时候,先判断标记,如果标记正在运行,直接推出,不管,然后标记状态为运行,在运行完成之后,标记为运行完成!
TimeSetEvent
不需要考虑同步弊:
如果操作时间很长,主界面会冻结
wm_timer在消息队列中只会存一份,多次触发,可能只执行一次