【发布时间】:2015-04-24 04:57:00
【问题描述】:
我正在开发的 Delphi 应用程序必须延迟一秒,有时甚至是两秒。我想使用最佳实践来编程这个延迟。在阅读有关 stackoverflow 上 Delphi 的 Sleep() 方法的条目时,我发现了这两个 cmets:
我信奉这样的格言:“如果你觉得需要使用 Sleep(),那你就做错了。” – 尼克霍奇斯 2012 年 3 月 12 日 1:36
@nick 确实如此。我的等价物是“没有问题可以通过睡眠来解决。” – 大卫赫弗南 2012 年 3 月 12 日 8:04
为了响应这个避免调用 Sleep() 的建议,以及我对使用 Delphi 的 TTimer 和 TEvent 类的理解,我编写了以下原型。我的问题是:
- 这是编程延迟的正确方法吗?
- 如果答案是肯定的,那为什么这比调用 Sleep() 更好?
type
TForm1 = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
public
EventManager: TEvent;
end;
TDoSomething = class(TThread)
public
procedure Execute; override;
procedure Delay;
end;
var
Form1: TForm1;
Something: TDoSomething;
implementation
{$R *.dfm}
procedure TDoSomething.Execute;
var
i: integer;
begin
FreeOnTerminate := true;
Form1.Timer1.Interval := 2000; // 2 second interval for a 2 second delay
Form1.EventManager := TEvent.Create;
for i := 1 to 10 do
begin
Delay;
writeln(TimeToStr(GetTime));
end;
FreeAndNil(Form1.EventManager);
end;
procedure TDoSomething.Delay;
begin
// Use a TTimer in concert with an instance of TEvent to implement a delay.
Form1.Timer1.Enabled := true;
Form1.EventManager.ResetEvent;
Form1.EventManager.WaitFor(INFINITE);
Form1.Timer1.Enabled := false;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Something := TDoSomething.Create;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
// Time is up. End the delay.
EventManager.SetEvent;
end;
【问题讨论】:
-
请解释什么必须延迟。 - 顺便说一句,“最佳方式”闻起来“主要基于意见”
-
应用程序与外部设备连接。外部设备通常会告知应用程序待机并等待一秒或多秒,然后才能获得可供应用程序使用的数据。
-
是推还是拉?当数据准备好(推送)时,外部设备会通知应用程序,还是必须一遍又一遍地询问,直到数据可用(拉取)?无论如何,您应该始终使用事件来等待。推无限超时或拉几毫秒
-
不必要的复杂,您可以完全删除计时器并等待事件 2000 毫秒而不是无限期。让它自己超时,而不是在定时器间隔后戳它。然后归结为
WaitForMultipleObjectsEx是否优于Sleep。我个人的看法,我没觉得 Sleep here 有什么问题。 -
我在工业自动化中一直使用睡眠 - 总是在后台线程上,但正是出于上述原因。有时,您必须等待现实世界中的某些事物不会或不会向您传达它们的准备情况,但它们仍然会以非常有规律和及时的方式准备好。它不一定是优雅的,但它是合乎逻辑的,可以理解的,并且有效。不是理想主义幻想中的“最佳”解决方案,而是务实现实主义世界中的“最佳”解决方案。
标签: delphi events timer delphi-xe2 sleep