2016-05-15 70 views
3

如何正確使用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

回答

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

最重要的部分解釋,從對方的回答:

注變量捕獲捕獲變量 - 不是值。如果一個 變量的值在通過構建一個匿名方法捕獲後發生變化,那麼所捕獲的匿名方法 變量的值也會發生變化,因爲它們是具有相同 存儲的變量。

要捕獲循環變量的值,包任務 創建一個單獨的函數:

+0

你真正的MVP m8 – ColdZer0