【问题标题】:Timer is lagging in the UI计时器在 UI 中滞后
【发布时间】:2020-11-04 17:24:21
【问题描述】:

我有一个用于秒表功能的TTimer 组件,并将TEdit 中的数据显示为'h:m:s --- 0.00 dollars',如下所示:

procedure TBillardApp.Timer1Timer(Sender: TObject);
begin
  sec:=sec+1;
  if sec >= 60 then
  begin
    sec:=0;
    min:=min+1;
  end;

  if min >= 60 then
  begin
    min:=0;
    hour:=hour+1;
  end;
  BillCounter1:=BillCounter1 + (1/(60*DBTextIndex.Field.Value));
  BillCounterF1:=Format('%1.2f', [BillCounter1]);
  AEdit6.Text:=inttostr(hour)+':'+inttostr(min)+':'+inttostr(sec)+' --- '+BillCounterF1+' dollars ';
end;

如您所见,在秒表中,有一个钞票柜台,应该每秒数钱。

在我的数据库中,我看到了BILLSTART_TIMEEND_TIMEDURATION_TIMESTARTEND 时间之间的差异),它们在数据库表中正确显示。

问题出在 UI 部分,在 TEdit 字段中,秒表和计费器滞后,并且不显示数据库中出现的数据。

有没有人遇到过这种问题?有没有办法解决这个问题?使用线程怎么样?这会减少 UI 延迟吗?

注意:我正在使用 Embarcadero Delphi XE7 Architect EditionMS Access 数据库。

【问题讨论】:

  • 计时器永远不会像您所需要的那样准确。 (毕竟 Windows 不是一个实时操作系统......)为什么不使用您在那里跟踪的任何内容的开始时间并将运行时间显示为FormatDateTime('hh:nn:ss',now-StartTimeValue)
  • 也许你不理解我,@ub_coding。我需要一个秒表功能,它从 0:0:0 开始,每秒计数。 START 时间和 END 时间仅来自数据库,与秒表前端功能无关。
  • @user14461368 正如 ub 所提到的,TTimer 不是实时的,因此可能会有一些滞后/漂移,这就是为什么它不利于准确跟踪时间的原因。 ub 建议您可以在秒表开始时保存开始日期/时间,例如来自Now(),然后在每个计时器事件上从Now() 中减去当前日期/时间中的值。这将为您提供每个计时器事件之间更准确的持续时间。请注意,这种方法会受到时钟变化的影响。来自用户、操作系统(网络时间同步等)、DST 更改……
  • @user14461368 话虽如此,Delphi 有一个实际的TStopWatch 类。我建议使用它来跟踪实际持续时间,并且只需使用TTimerTStopWatch 当前报告每个事件的任何持续时间来更新 UI。 TStopWatchTTimer 更准确,因为它不依赖于操作系统时钟的更改。
  • @ub_coding,你的建议解决了我的问题。我插入了另一个显示现在时间的 TEdit,我从开始时间中减去它以获得秒表功能。谢谢。

标签: delphi timer delphi-xe7


【解决方案1】:

UI 计时器不能保证在指定的时间段内准确触发。这是正常的,并且预计它们在过期后会有所触发。

相反,您应该通过其他方式跟踪时间。例如系统时钟,或者在您的情况下,TStopwatch 似乎是最准确的。以比当前更高的频率触发计时器,并检查秒表以查看 UI 是否需要更新。

【讨论】:

    猜你喜欢
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多