![]() |
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:
|
AW: TTask & Synchronize Verständnisproblem
Dafür gibt es ja Prioritäten für Threads und Prozesse. Es macht doch keinen Sinn dann z.B. drei Kerne voll auszulasten und den vierten leer laufen zu lassen nur für den Fall, dass er benötigt wird...
|
AW: TTask & Synchronize Verständnisproblem
Gerade die Downloads sind ja in der Regel nicht sonderlich prozessorintensiv. Solange das Warten auf den Empfang des nächsten Datenpakets bzw. dessen Schreiben auf Platte nicht mit einem Busy-Wait implementiert ist, regelt sich das eigentlich ganz von selber.
Andererseits geht auch hier nichts über reale Messungen. |
AW: TTask & Synchronize Verständnisproblem
Zitat:
Aber für einen Download gelten andere Regeln, z.B. wenn der Server nur 1x die IP zu lässt. Je nach Server und Bandbreite sind ca. 4 Thread optimal (bei großen Dateien) bei Tausenden kleinen sind mehr Thread besser... Für den Download und die Verarbeitung der Daten empfehle ich sowas sie meine ![]() Wie man es implementiert ist fast egal - man kann auch einfach "nur" eine Anzahl von Workerthreads per Hand erzeugen und so die Daten verarbeiten. Mavarik |
AW: TTask & Synchronize Verständnisproblem
Zitat:
|
AW: TTask & Synchronize Verständnisproblem
Zitat:
Zitat:
Aber vielleicht sollte man diese Theorien mal gegen ein Testsystem laufen lassen... :stupid: Mavarik |
AW: TTask & Synchronize Verständnisproblem
Ich stelle gerade fest, daß wir uns ziemlich weit vom ursprünglichen Thema entfernt haben :oops:
|
AW: TTask & Synchronize Verständnisproblem
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:12 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