Delphi 延迟执行
Delayed execution in Delphi
是否可以在调用程序结束后延迟启动程序?
procedure StartLoop;
begin
DoSomething;
end;
procedure FormCreate(...);
begin
if ParamStr(1)='start' then StartLoop;
end;
StartLoop 将在 inside FormCreate 中被调用,FormCreate 将等待,并不仅阻止 FormCreate 本身的进一步执行,还阻止在它之后执行的进一步过程(FormShow 等) .), 直到 StartLoop 结束才会显示表单。
我需要等到 FormCreate 结束,然后 运行 StartLoop(不使用线程)。
最简单的方法是使用定时器。
让您在设计时在表单上创建 DelayTimer
并设置所需的周期和 Enabled = False
(您也可以动态创建)。为其分配事件处理程序:
procedure TFormXX.DelayTimerTimer(Sender: TObject);
begin
DelayTimer.Enabled := False; // works only once
StartLoop;
end;
在表单初始化例程中启动这个计时器:
procedure FormCreate(...);
begin
if ParamStr(1)='start' then
DelayTimer.Enabled := True;
end;
也许您想稍后启动计时器,例如 - 在 OnShow
中,如果您的应用程序在创建期间执行一些连续的操作。
另一个解决方案可能是将您的 DoSomething
方法包装到任务中:
uses
System.Threading;
procedure TForm2.DoSomething;
begin
Sleep(2000);
Caption := 'Done';
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
if ParamStr(1) = 'start' then
TTask.Run(
procedure
begin
DoSomething
end);
end;
如果您使用的是 10.2 Tokyo 或更高版本,您可以使用 TThread.ForceQueue()
:
procedure TMyForm.FormCreate(Sender: TObject);
begin
if ParamStr(1) = 'start' then
TThread.ForceQueue(nil, StartLoop);
end;
否则,您可以使用PostMessage()
代替:
const
WM_STARTLOOP = WM_USER + 1;
procedure TMyForm.FormCreate(Sender: TObject);
begin
if ParamStr(1) = 'start' then
PostMessage(Handle, WM_STARTLOOP, 0, 0);
end;
procedure TMyForm.WndProc(var Message: TMessage);
begin
if Message.Msg = WM_STARTLOOP then
StartLoop
else
inherited;
end;
是否可以在调用程序结束后延迟启动程序?
procedure StartLoop;
begin
DoSomething;
end;
procedure FormCreate(...);
begin
if ParamStr(1)='start' then StartLoop;
end;
StartLoop 将在 inside FormCreate 中被调用,FormCreate 将等待,并不仅阻止 FormCreate 本身的进一步执行,还阻止在它之后执行的进一步过程(FormShow 等) .), 直到 StartLoop 结束才会显示表单。
我需要等到 FormCreate 结束,然后 运行 StartLoop(不使用线程)。
最简单的方法是使用定时器。
让您在设计时在表单上创建 DelayTimer
并设置所需的周期和 Enabled = False
(您也可以动态创建)。为其分配事件处理程序:
procedure TFormXX.DelayTimerTimer(Sender: TObject);
begin
DelayTimer.Enabled := False; // works only once
StartLoop;
end;
在表单初始化例程中启动这个计时器:
procedure FormCreate(...);
begin
if ParamStr(1)='start' then
DelayTimer.Enabled := True;
end;
也许您想稍后启动计时器,例如 - 在 OnShow
中,如果您的应用程序在创建期间执行一些连续的操作。
另一个解决方案可能是将您的 DoSomething
方法包装到任务中:
uses
System.Threading;
procedure TForm2.DoSomething;
begin
Sleep(2000);
Caption := 'Done';
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
if ParamStr(1) = 'start' then
TTask.Run(
procedure
begin
DoSomething
end);
end;
如果您使用的是 10.2 Tokyo 或更高版本,您可以使用 TThread.ForceQueue()
:
procedure TMyForm.FormCreate(Sender: TObject);
begin
if ParamStr(1) = 'start' then
TThread.ForceQueue(nil, StartLoop);
end;
否则,您可以使用PostMessage()
代替:
const
WM_STARTLOOP = WM_USER + 1;
procedure TMyForm.FormCreate(Sender: TObject);
begin
if ParamStr(1) = 'start' then
PostMessage(Handle, WM_STARTLOOP, 0, 0);
end;
procedure TMyForm.WndProc(var Message: TMessage);
begin
if Message.Msg = WM_STARTLOOP then
StartLoop
else
inherited;
end;