Отсроченное выполнение в Delphi - PullRequest
0 голосов
/ 13 декабря 2018

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

procedure StartLoop;
begin
  DoSomething;
end;

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

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

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

Ответы [ 3 ]

0 голосов
/ 13 декабря 2018

Другим решением может быть добавление вашего метода 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;
0 голосов
/ 13 декабря 2018

Если вы используете 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;
0 голосов
/ 13 декабря 2018

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

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

...