![]() |
Delphi-Version: 10 Berlin
TTask & Synchronize Verständnisproblem
Hallo!
Habe ein Verständnisproblem bei TTask. Wollte nur Variablen der "Hauptprocedur" an den Task beim Start übergeben. Jedoch bekomme ich nicht die richtigen Werte (meist -> 1,2,3,4,6,6). Ich verstehe ja, das die Tasks unabhängig/zeitversetzt gestartet werden - nur wie bekomme ich Variablen "synchronisiert" beim Start des Tasks in den Task. Hoffe habe mich irgendwie verständlich ausgedrückt. :?
Delphi-Quellcode:
SetLength(tasks, anz);
for i := 0 to anz - 1 do begin fn := Files[i].Filename; s := fn + ' wird heruntergeladen...'; line := Memo1.Lines.Add(s); Files[i].Zeilennummer := line; tasks[i] := TTask.Create ( procedure () var j: Integer; tfn, ss: String; begin TInterlocked.Exchange(j, i); // !!?? zu spät? TThread.Synchronize(nil, procedure begin tfn := fn; // !!?? zu spät? end); ok := DownloadFile(tfn); // Herunterladen - zeitintensiv TThread.Synchronize(nil, procedure begin ss := tfn + ' wurde heruntergeladen.'; Memo1.Lines.Add(IntToStr(j) + ' - ' + ss); end); end); tasks[i].Start; end; |
AW: TTask & Synchronize Verständnisproblem
Innerhalb der anonymen Methode wird immer der gerade aktuelle Wert der Variablen i und fn verwendet. Da dieser zur Ausführung in der Task schon ein anderer sein kann als zur Erzeugung der Task, kommt es zu diesem Verhalten. Du kannst aber die anonyme Methode auch über eine Funktion erzeugen lassen, der du den i- und fn-Parameter mitgibst. Dabei erhalten die Parameter ihre Werte aus dem Hauptthread und stehen der Task exklusiv zur Verfügung (Code ungetestet).
Delphi-Quellcode:
function CreateMyTask(I: Integer; fn: string; HandleResult: TProc<string>): TProc;
begin result := procedure () var ok: Boolean; begin ok := DownloadFile(fn); // Herunterladen - zeitintensiv TThread.Synchronize(nil, procedure var ss: String; begin if ok then begin ss := fn + ' wurde heruntergeladen.'; end else begin ss := fn + ' wurde nicht heruntergeladen.'; end; HandleResult(IntToStr(i) + ' - ' + ss); end); end; end; ... SetLength(tasks, anz); for i := 0 to anz - 1 do begin fn := Files[i].Filename; s := fn + ' wird heruntergeladen...'; line := Memo1.Lines.Add(s); Files[i].Zeilennummer := line; tasks[i] := TTask.Create(CreateMyTask(i, fn, procedure (Arg: string) begin Memo1.Lines.Add(Arg); end)); tasks[i].Start; end; |
AW: TTask & Synchronize Verständnisproblem
Und spätestens hier sollte man anhand der Lesbarkeit sehen dass es besser wäre das Herunterladen und das Anzeigen in der Oberfläche zu trennen. Auf Dauer bleibt es bestimmt nicht bei einem einfachen
Delphi-Quellcode:
... :warn:
Memo1.Lines.Add(..)
|
AW: TTask & Synchronize Verständnisproblem
Zitat:
Dazu kommt noch, daß das Synchronize eh die letzte Aktion der Task ist und somit auch durch ein Queue ersetzt werden kann.
Delphi-Quellcode:
function CreateMyTask(I: Integer; fn: string; HandleResult: TProc<Integer, string, Boolean>): TProc;
begin result := procedure () var ok: Boolean; begin ok := DownloadFile(fn); // Herunterladen - zeitintensiv TThread.Queue(nil, procedure begin HandleResult(i, fn, ok); end); end; end; function CreateResultHandler(Target: TStrings): TProc<Integer, string, Boolean>; begin Result := procedure (Idx: Integer; FileName: string; OK: Boolean) var ss: string; begin if OK then begin ss := FileName + ' wurde heruntergeladen.'; end else begin ss := FileName + ' wurde nicht heruntergeladen.'; end; Target.Add(ss); end; end; ... SetLength(tasks, anz); for i := 0 to anz - 1 do begin fn := Files[i].Filename; s := fn + ' wird heruntergeladen...'; line := Memo1.Lines.Add(s); Files[i].Zeilennummer := line; tasks[i] := TTask.Create(CreateMyTask(i, fn, CreateResultHandler(Memo1.Lines))); tasks[i].Start; end; |
AW: TTask & Synchronize Verständnisproblem
Oder eher nicht...
Ok, der ThreadPool managed nur so viele gleichzeitige Thread wie es für die CPU - Core Anzahl sinnvoll ist, aber ist das auch sinnvoll für einen download? i.d.R. nicht... Hier würde ich die Anzahl begrenzen. Das geht nicht über den Threadpool. Mavarik |
AW: TTask & Synchronize Verständnisproblem
Zitat:
Zitat:
|
AW: TTask & Synchronize Verständnisproblem
Zitat:
Zitat:
|
AW: TTask & Synchronize Verständnisproblem
Zitat:
|
AW: TTask & Synchronize Verständnisproblem
Warum sollte man denn das Maximum geringer setzen wollen als die Anzahl der CPU Kerne?
Wenn man weiß, dass eine Aktion z.B. die Festplatte sehr stark beansprucht, ist ein Threadpool eher nicht geeignet, weil man dann ja gar nicht viele Tasks parallel möchte. |
AW: TTask & Synchronize Verständnisproblem
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:46 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz