如何使用for循环内的TTask threadin delphi 10

问题描述:

如何正确使用for循环内的TTask?我不断获得备忘录中ListBox1的最后一个项目,例如,如果我在ListBox1中有5个项目,我在memo1中获得了最后一个ListBox1项目5次!,代码有什么问题?如何使用for循环内的TTask threadin delphi 10

var 
    i: Integer; 
    lPath: string; 
begin 
    for i := 0 to ListBox1.Items.Count - 1 do 
    begin 
    lPath := ListBox1.Items.Strings[i]; 
    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; 
end; 
+0

@Phil:这有什么好做OTL。这是德尔福10西雅图/柏林的新并行处理功能。 –

+0

它可能是,但我不知道如何将它应用到我的代码@PhilRoss – ColdZer0

这里是适应代码:

// 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://*.com/a/13349520/101087

最重要的部分解释,从对方的回答:

注变量捕获捕获变量 - 不是值。如果一个 变量的值在通过构建一个匿名方法捕获后发生变化,那么所捕获的匿名方法 变量的值也会发生变化,因为它们是具有相同 存储的变量。

要捕获循环变量的值,包任务 创建一个单独的函数:

+0

你真正的MVP m8 – ColdZer0