uses Threading;
procedure TForm2.Button1Click(Sender: TObject);
begin
DownloadWithoutBlockingUI;
end;
procedure TForm2.Download;
begin
//something long-lasting
for var i:=0 to 500 do begin
Sleep(1);
//don't change anything in the UI here!
end;
end;
procedure TForm2.DownloadWithoutBlockingUI;
var
aTask: ITask;
begin
Label1.Caption:='Start...';
//preparation of the parallel task
aTask:=TTask.Create(procedure ()
begin
//what will be executed
Download;
//after completion I will arrange UI modification
TThread.Queue(nil,
procedure
begin
Label1.Caption:='Finished';
end
);
end);
//start of a parallel task
aTask.Start;
end;
2条答案
按热度按时间zynd9foi1#
在主UI线程中执行任何UI阻塞操作从来都不是一个好主意,总是在辅助线程中执行它们,并根据需要使其与UI线程同步。 Delphi 为此提供了一个
TThread
类,您可以根据需要从它的虚拟Execute()
方法派生并重写它。或者,使用它的CreateAnonymousThread()
方法。Indy也有自己的
TIdThread
扩展到TThread
,以及TIdThreadComponent
组件 Package 器。但是,如果您必须使用主UI线程,那么Indy确实有一个
TIdAntiFreeze
组件,允许主UI线程在UI阻塞Indy操作正在进行时继续处理消息。只需将TIdAntiFreeze
放入MainForm(或根据需要在代码中示例化它),Indy将处理其余的工作。请注意,
TIdAntiFreeze
基本上只是Application.ProcessMessages()
的 Package 器,允许Indy操作周期性地泵消息队列,因此这与ProcessMessages()
常见的所有相同的重新进入风险相同,因此请小心使用。b1payxdu2#
我不知道这是否也适用于IdFtp,但通常最简单的方法是这样的: