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;