如何在TTask threadin delphi 10中使用for循环

时间:2016-05-15 00:02:16

标签: delphi concurrency delphi-10-seattle ppl-delphi

如何正确使用TTask中的循环?我一直只在备忘录中获得ListBox1的最后一项,例如,如果我在ListBox1中有5个项目,我在memo1中得到ListBox1的最后一项5次!,代码有什么问题?

sender

1 个答案:

答案 0 :(得分:3)

以下是改编的代码:

// Current method:
procedure TMyForm.XYZ
var
  i: Integer;
  lPath: string;
begin
  for i := 0 to ListBox1.Items.Count - 1 do
  begin
    lPath := ListBox1.Items.Strings[i];
    StartDownloadTask(lPath);
  end;
end;

// Put task creation in separate method:
procedure TMyForm.StartDownloadTask(lPath: string)
begin
    TTask.Create(
      procedure
      var
        lHTTP: TIdHTTP;
        IdSSL: TIdSSLIOHandlerSocketOpenSSL;
      begin
        lHTTP := TIdHTTP.Create(nil);

        TThread.Synchronize(nil,
          procedure
          begin
            Form1.Caption := 'Task Running...';
          end
        );

        try
          lHTTP.ReadTimeout := 30000;
          lHTTP.HandleRedirects := True;
          IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(lHTTP);
          IdSSL.SSLOptions.Method := sslvTLSv1;
          IdSSL.SSLOptions.Mode := sslmClient;
          lHTTP.IOHandler := IdSSL;
        Finally
          try
            lHTTP.Get('http://website.com/'+lPath, TStream(nil));
          Finally
            lHTTP.Free;
          end;
        end;

        TThread.Synchronize(nil,
          procedure
          begin
            Memo1.Lines.Add(lPath);
           end
        );

      end
    ).Start;
end;

有关背景的说明,请参阅https://stackoverflow.com/a/13349520/101087

中的说明

另一个答案最重要的部分:

  

请注意,变量捕获捕获变量而不是值。如果一个   通过构造一个变量来捕获变量后的值变化   匿名方法,匿名方法的变量值   捕获的变化也是如此,因为它们是相同的变量   存储

     

要捕获循环变量的,请包装创建任务   在一个单独的功能中: