Отсроченное выполнение в Delphi

Можно ли запустить процедуру с задержкой после завершения вызывающей процедуры?

procedure StartLoop;
begin
  DoSomething;
end;

procedure FormCreate(...);
begin
  if ParamStr(1)='start' then StartLoop;
end;

StartLoop будет вызываться внутри FormCreate, а FormCreate будет ожидать и заблокировать дальнейшее выполнение не только самого FormCreate, но также и последующих процедур, выполняющихся после него (FormShow и т. Д.), И форма не будет отображаться до тех пор, пока не завершится StartLoop.

Мне нужно дождаться окончания FormCreate и запустить StartLoop после этого (без использования потоков).

3 ответа

Решение

Самый простой способ - использовать таймер.

Позвольте вам создать 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, если ваше приложение выполняет некоторые непрерывные действия во время создания.

Если вы используете 10.2 Токио или позже, вы можете использовать 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;

Другим решением может быть упаковка 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;
Другие вопросы по тегам