delphi 我们如何在不阻塞UI的情况下进行IdFTP.Get?

vshtjzan  于 2023-06-22  发布在  其他
关注(0)|答案(2)|浏览(169)

我正在使用IdFTP浏览和列出一个小型FTP文件夹的内容。
我想与双击用户可以开始下载该文件。
我注意到FTP.Get运行良好,但存在UI阻塞。
你能告诉我一个可行的解决方法吗?

zynd9foi

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()常见的所有相同的重新进入风险相同,因此请小心使用。

b1payxdu

b1payxdu2#

我不知道这是否也适用于IdFtp,但通常最简单的方法是这样的:

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;

相关问题