Delphi-PRAXiS
Seite 1 von 5  1 23     Letzte »    

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

Smiley 24. Aug 2019 17:19

TTask.WaitForAll hängt
 
Ich versuche mein Mainform beweglich zu halten, nachdem ich ein Programm starte, das sehr lange zum fertigstellen braucht.
Daher habe ich das Programm in einem TTask in den Hintergrund geschickt.
Das Problem ist nur, dass ich abfragen muss, wann der Prozess beendet ist.
Es wird immer wieder beschrieben, dass man mit WaitFoAll auf die Beendigung aller Tasks warten kann.
Das funktioniert bei mir aber nicht, er bleibt in der WaitForAll Abfrage für immer stecken.
Daher habe ich es mit einer separaten Variable gemacht um die Beendigung abzufragen, das funktioniert auch.

Aber warum funktioniert das WaitForAll bzw. WaitForAny nicht, das ist dafür doch gedacht ???

Hier mein Code:
Delphi-Quellcode:
  Verz: String;
  j, AktLine: Integer;
  StartFolder, ProgPath: String;
  StartTime: TTime;
  LTaskRun: boolean;
  tasks: array of ITask;

implementation

{$R *.dfm}

// *****************************************************************************
procedure TForm1.Button1Click(Sender: TObject);
var
  lstatus: boolean;

begin
  lStatus:=False;
  LTaskRun := true;
  Setlength(tasks, 1);

  tasks[0] := TTask.Create(
    procedure
    begin
      DirList;
    end);
  tasks[0].Start;

  lstatus := TTask.WaitForAll(tasks);
  ShowMessage('Nach WaitAll');

  repeat
    application.ProcessMessages;
  until not LTaskRun;

end;
Wenn ich das WaitforAll rausnehme funktioniert alles wie gewünscht.
Einen 2ten Task aufmachen versuche ich erst wenn ich es mit einem vernüftig hinbekommen habe.
Dann kommt auch noch das Sychronize mit rein.
Ein Schritt nach dem anderen.
Wärend im Hintergrund eine Liste in einem Grid eingfügt wird oder in eine DB, soll das Hauptfenster nicht "Programm ausgelastet" anzeigen und noch verschiebbar sein.

Luckie 24. Aug 2019 17:23

AW: TTask.WaitForAll hängt
 
Ich kenne mich mit Tasks nicht so aus, aber wenn der Task so wie so schon im Hintergrund läuft, wozu die Schleife mit dem ProcessMessages?

Smiley 24. Aug 2019 17:30

AW: TTask.WaitForAll hängt
 
Weil ich wissen will wann der Task beendet ist.
Besser wäre es natürlich ich bekäme einen event der mir sagt, dass der Task fertig ist.
Das ist aber erst der nächste Schritt.
wie das geht habe ich noch nicht gefunden.

stahli 24. Aug 2019 17:49

AW: TTask.WaitForAll hängt
 
So ganz konkret kann ich jetzt nicht helfen, aber hier mal 3 Videos zu Threads & Co:

https://youtu.be/WOc89TF8l-8
https://youtu.be/Jhcpgjs1uPA
https://youtu.be/0p7kbE8TkWI

Im ersten sind Tasks explizit mit als Thema aufgeführt.

(Werde ich mir auch gleich nochmal anschauen. Ich war sowieso gerade auf der Suche nach interessanten Programmier-Videos. :-) )

Schokohase 24. Aug 2019 18:23

AW: TTask.WaitForAll hängt
 
Also Wait heißt übersetzt Warten und genau das passiert.

Der Aufruf WaitForAll oder WaitForAny ist blockierend.
Diese Repeat Schleife kannst du ersatzlos streichen, denn wenn du da hin kommst dann ist schon alles vorbei.

Smiley 24. Aug 2019 18:46

AW: TTask.WaitForAll hängt
 
Das ist schon klar Schokohase, dafür war es auch gedacht, das Repeat habe ich lediglich nicht gelöscht, aber dorthin komme ich ja nie, genau das ist ja das Problem.
Das WaitForAll wartet eben unendlich, auch wenn der Task lange abgelaufen ist, zum Reppeat komme ich ja gar nicht.

Danke Stahli für die Links, das erste Video von Bernd Ua kannte ich noch nicht, das ist ganz gut.
Das von Daniel war auch gut beschäftigt sich aber hauptsächlich nur mit dem Deadlock und Synchronize, bei Bernd Ua ist etwas mehr Code zu sehen.

Luckie 24. Aug 2019 18:51

AW: TTask.WaitForAll hängt
 
Zitat:

Zitat von Smiley (Beitrag 1442992)
Weil ich wissen will wann der Task beendet ist.

Aber der Code wird doch erst ausgeführt, wenn die ShowMessage angezeigt wird. Und da ist der Task schon fertig. Der Code wird ja linear abgearbeitet.

Smiley 24. Aug 2019 19:01

AW: TTask.WaitForAll hängt
 
Zum showmessage komme ich nicht, da er ja in waitforall hängen bleibt.
Man könnte hier zu beginn von der Clickroutine den Butto auf disabled stellen und nach waitforall auf enabled, dann erkennt man einen Sinn in der Abfrage

Smiley 24. Aug 2019 19:05

AW: TTask.WaitForAll hängt
 
procedure TForm1.Button1Click(Sender: TObject);
var
lstatus: boolean;

begin
lStatus:=False;
LTaskRun := true;
Setlength(tasks, 1);
Button1.enabled:=False;

tasks[0] := TTask.Create(
procedure
begin
DirList; // Hier ist das Prgramm das lange braucht und im Hintergrund läuft
end);
tasks[0].Start;

lstatus := TTask.WaitForAll(tasks);
// Hier kommt man nie hin.
Button1.enabled:=True;

end;

Smiley 24. Aug 2019 20:19

AW: TTask.WaitForAll hängt
 
Habe mir jetzt alle Videos angesehen,
Das zeite Video von Olaf Monien https://youtu.be/Jhcpgjs1uPA ist das Beste für meine Zwecke um mit TTask zu arbeiten.
Das dritte von Daniel Wolf ist auch sehr gut (kannte ich schon) beschreibt aber mehr nur die Problematik Synchronisierung und der Deadlock vermeidung.

Danke Stahli für die Links

Ich weiß zwar noch nicht warum das mit dem WaitforAll nicht funktioniert, vermute aber dass es an einer anderen Stelle eingesetzt wird und normalerweis so auch nicht benutzt wird.
Davon ist in den Videos auch nicht die Rede.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:40 Uhr.
Seite 1 von 5  1 23     Letzte »    

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