Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi TTask.WaitForAll hängt (https://www.delphipraxis.net/208054-ttask-waitforall-haengt.html)

stalkingwolf 2. Jun 2021 11:20

TTask.WaitForAll hängt
 
Ich steig nicht ganz durch wie waitforAll/waitforAny funktioniert.
Ich habe nach http://docwiki.embarcadero.com/RADSt...amming_Library
meinen Task hinzugefügt.

Wenn ich diesen mit tasks[0].start; anstarte dann funktioniert alles einwandfrei.
Packe ich dann dahinter TTask.WaitForAll(tasks); dann kommt er nie wieder. Keine UI Aktualisierung und meine gesamte UI ist danach wie wie eingefroren.

Pack ich ein TTask.WaitForAll(tasks,10000); rein, dann rennt mein Task nach den 10sek durch und ich erhalte die gesamte UI Aktualisierung wieder.

Meine UI Aktualiserung mache ich mit
Code:
TThread.Synchronize(NIL,
Procedure
begin
end
Was übersehe ich hier? Was gibt dem WaitForAll die Info das es durch ist? Kein exit oder end in der procedure?

Uwe Raabe 2. Jun 2021 11:39

AW: TTask.WaitForAll hängt
 
Das WaitForAll blockiert den Hauptthread und somit wird das Synchronize nicht abgearbeitet. Wenn du auf das Ende der Task warten musst, dann ist das ganze Konzept vielleicht nicht das richtige.

stalkingwolf 2. Jun 2021 12:22

AW: TTask.WaitForAll hängt
 
Ok verstehe.
Muss ich mir was anderes ausdenken.

softtouch 2. Jun 2021 20:59

AW: TTask.WaitForAll hängt
 
Strate am Ende des Tasks einfach einen Timer, dessen code dann ausgeführt wird. So mache ich es auch immer. Nichts wird blockiert.

himitsu 3. Jun 2021 08:22

AW: TTask.WaitForAll hängt
 
Timer?
Delphi-Referenz durchsuchenTThread.Queue


Oder im Hauptthread nicht nur stumpf warten, sondern dabei auch die Messages verarbeiten.
(siehe sowas wie Application.ProcressMessages oder Hier im Forum suchenDelay)

Sinspin 3. Jun 2021 13:25

AW: TTask.WaitForAll hängt
 
Bei mir senden Threads eine Message oder ändern eine Variable wenn sie fertig sind oder was zu berichten haben.

WaitFor macht nur Sinn wenn man das Ergebnis unbedingt braucht bevor man weiter machen kann.
Schicke jemanden essen hohlen -> warte auf das essen -> stille deinen Hunger. :roll:

Uwe Raabe 3. Jun 2021 13:35

AW: TTask.WaitForAll hängt
 
Die simpelste Lösung wäre am Ende der Task-Methode ein
Delphi-Quellcode:
TThread.Queue(nil, ...)
aufzurufen.

Wenn aber der Code nach dem Task-Aufruf erst auf das Ende der Task warten muss, dann ist die Task vielleicht nicht das richtige Konzept.

stalkingwolf 4. Jun 2021 08:26

AW: TTask.WaitForAll hängt
 
Zitat:

Zitat von Sinspin (Beitrag 1490595)
WaitFor macht nur Sinn wenn man das Ergebnis unbedingt braucht bevor man weiter machen kann.
Schicke jemanden essen hohlen -> warte auf das essen -> stille deinen Hunger. :roll:

Was bei mir der Fall ist. Weil ich Daten von einem Server lade und es keinen Sinn ergibt vorher was anderes zu machen bis die Daten unten sind ;-)

Ich habe nun in meinem Task die UI disabled und dann kann der Anwender nicht irgendwo herumdrücken.

Uwe Raabe 4. Jun 2021 08:54

AW: TTask.WaitForAll hängt
 
Zitat:

Zitat von stalkingwolf (Beitrag 1490641)
Weil ich Daten von einem Server lade und es keinen Sinn ergibt vorher was anderes zu machen bis die Daten unten sind

Dann spar dir doch die Task ganz und führe die Abfrage im Hauptthread aus.

stalkingwolf 4. Jun 2021 09:17

AW: TTask.WaitForAll hängt
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1490645)
Zitat:

Zitat von stalkingwolf (Beitrag 1490641)
Weil ich Daten von einem Server lade und es keinen Sinn ergibt vorher was anderes zu machen bis die Daten unten sind

Dann spar dir doch die Task ganz und führe die Abfrage im Hauptthread aus.

Dann konnte ich meine UI nicht aktualisieren. Der Grund warum ich das überhaupt gemacht hatte.
Meine Fortschrittsanzeige hat nicht mehr funktioniert weil ab 10.3 das mit application.processmessage geändert wurde.

KodeZwerg 4. Jun 2021 10:37

AW: TTask.WaitForAll hängt
 
Bevor ich eine UI komplett lahmlege würde ich eher ein dynamisch generiertes Formular mit einer ProgressBar drauf Modal darstellen lassen. ("Downloading Data... please wait...")
TThread mit Syncronize sorgt für ein Update der UI.
Auch ein Abbrechen button sollte nicht fehlen.

Ich hoffe Du verstehst wie ich es meine.

jziersch 4. Jun 2021 10:47

AW: TTask.WaitForAll hängt
 
Anstatt Synchronize verwende ich nun AtomicIncrement im Task um ein Flag zu setzen wenn Daten zur Anzeige fertig sind. Dieses Flag frage ich im Haupthread in einem Timer event periodisch ab und rufe, falls das Flag gesetzt ist, die Daten aus einem entsprechenden Objekt ab.

Mittels AtomicIncrement kann man auch einem Task mitteilen, dass er abbrechen soll.

stalkingwolf 7. Jun 2021 08:19

AW: TTask.WaitForAll hängt
 
Zitat:

Zitat von KodeZwerg (Beitrag 1490651)
Bevor ich eine UI komplett lahmlege würde ich eher ein dynamisch generiertes Formular mit einer ProgressBar drauf Modal darstellen lassen. ("Downloading Data... please wait...")
TThread mit Syncronize sorgt für ein Update der UI.
Auch ein Abbrechen button sollte nicht fehlen.

Ich hoffe Du verstehst wie ich es meine.

Ja und das habe ich mit einem Callpout gemacht auf welchem ein Progressbar und Label ist, weil ich kein neues Formular haben wollte.
Die Zugriffe habe ich mit TThread.Syncronize gelöst.

Mit ging es nun nur um das waitForAll weil es mir die APP komplett still gelelgt hat. Aber ich habe es anders gelöst. Ein abbrechen vom Download macht eh keiner, weil die Daten benötigt werden.

Dennoch Danke für das Feedback.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:54 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz