Отсроченное выполнение в 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;