Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Delphi TTask bei FMX startet nicht (Delphi 10.2) (https://www.delphipraxis.net/194648-ttask-bei-fmx-startet-nicht-delphi-10-2-a.html)

nytaiceman 17. Dez 2017 07:38

TTask bei FMX startet nicht (Delphi 10.2)
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo,

Ich arbeite mit Delphi 10.2. Wenn ich TTasks verwenden möchte, habe ich ein ungleiches Verhalten zwischen VCL und FMX basierter Kompilierung.

Der Code der ausgeführt wird, ist bei beiden Projekten derselbe:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
// uses System.Threading
var
  aTask: ITask;

begin
 ShowMessage ('Before TTask');

 aTask := TTask.Create (procedure ()
   begin
     sleep (5000);
     ShowMessage ('During TTask');
   end);

 aTask.Start;

 ShowMessage ('After TTask');
end;
Aber nur in der reinen VCL Kompilierung startet der TTask.
Hat jemand eine Idee?

Rollo62 17. Dez 2017 12:42

AW: TTask bei FMX startet nicht (Delphi 10.2)
 
Versuch mal das:

Delphi-Quellcode:
    ShowMessage ('1. Before TTask');

    TTask.Run(  procedure
                begin

                  sleep (5000);

                  TThread.Synchronize(nil,
                                      procedure
                                      begin
                                          ShowMessage ('2. During TTask');
                                      end);


                end);

    ShowMessage ('3. After TTask');
Du erwartest hoffentlich nicht das hier 1. 2. 3. in der Reihenfolge ausgeführt wird.
Der Task wir ja im Hintergrund laufen, und irgendwann nach 5000ms ausgelöst werden.
Muss dann mit Queue oder Synchronize mit dem Hauptthread synchrnisiert werden, ansosnten gibt es Crash.

Die Reihenfolge ist
1. Before
2. After (fast zeitgleich)
// hier kannst du aber normal im Hauptthread andere Dinge machen, es bleibt reaktiv.
3. During (ca. 5000ms danach).

Ist es das was du erreichen möchtest ?

Rollo

himitsu 17. Dez 2017 12:57

AW: TTask bei FMX startet nicht (Delphi 10.2)
 
Wird es nicht ausgeführt und oder wird nur nichts ausgeführt?

Vorallem bei der VCL hast du einen eklatanten Fehler, denn die VCL ist nicht threadsave, also darf ShowMessage NIEMALS innerhalb eines Task/Thread ausgeführt werden!
Und für FMX gilt grundsätzlich erstmal das Selbe.

Du hast doch garantiert im Debugger mal nachgesehn, ob der Aufruf im Task ausgeführt wird?
Und wie nytaiceman bereits erwähnte, kann "during" nur nach "after" kommen, da TTask.Run+Start nur anweist, dass der Task bald gestartet wird, diese Befehle umgehend zurück kommen und umgehend das
Delphi-Quellcode:
ShowMessage('3. After TTask');
ausführen.

nytaiceman 17. Dez 2017 13:34

AW: TTask bei FMX startet nicht (Delphi 10.2)
 
Vielen Dank an Euch beide!

Mir war die Reihenfolge klar, ich möchte ja den Taskinhalt asynchron ausführen.
Nur habe ich nicht verstanden das ich die Threads (Main und den Task) synchronisieren muss resp. dass die VCL Implementierung auch ohne den Sync funktionierte.

Ich habe nun bei beiden Beispielen denselben Aufruf laufen lassen und das Ergebnis ist bei beiden dasselbe und korrekt:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
// uses System.Threading
var
  aTask: ITask;

begin
 ShowMessage ('Before TTask');

  aTask := TTask.Create (procedure
  begin

    sleep (5000);

    TThread.Synchronize(nil,
      procedure
      begin
        ShowMessage ('During TTask');
      end);

  end);

 aTask.Start;

 ShowMessage ('After TTask');
end;
Die Messages erscheinen bei VCL und FMX in der gewünschten Reihenfolge:
1. "Before TTask"
2. "After TTask"
3. "During TTask"

himitsu 17. Dez 2017 14:09

AW: TTask bei FMX startet nicht (Delphi 10.2)
 
Dass es teilweise funktioniert hatte, war praktisch nur ein Zufall.

Wenn es nur Aynchron, aber ebenfalls im Hauptthread laufen soll, dann nimm einfach TThread.Queue .
Das ist wie Synchronize, nur das Synchronize direkt ausgeführt und bis nach der Ausführung gewartet wird, und während Queue nur den Aufruf abschickt und direkt weitermacht.

ABER, aus den Hauptthread heraus arbeitet Queue wie Syncronize und daher wurde nun endlich TThread.ForceQueue eingebaut, was richtig funktioniert.
http://www.delphipraxis.net/179193-t...der-queue.html

Delphi-Referenz durchsuchenTThread.Synchronize
Delphi-Referenz durchsuchenTThread.Queue
Delphi-Referenz durchsuchenTThread.ForceQueue

Delphi-Quellcode:
TThread.ForceQueue(nil, procedure
  begin
    ShowMessage('During TTask');
  end);
Wie gesagt, so wird alles im Hauptthread ausgeführt, nur eben nicht sofort, sondern wenn er das nächste Mal Zeit hat.

LTE5 17. Dez 2017 14:17

AW: TTask bei FMX startet nicht (Delphi 10.2)
 
Ist ForceQueue also dasselbe wie Queue aus dem Hauptthread?

Oder anders gefragt: da wo ich Queue aus dem Hauptthread aufrufe, sollte besser ForceQueue genutzt werden?

himitsu 17. Dez 2017 14:29

AW: TTask bei FMX startet nicht (Delphi 10.2)
 
Genau.
ForceQueue ist in Threads das Gleiche wie Queue.
Im Hauptthread aufgerufen arbeitet Queue aber "falsch".

Man dachte sich es zu optimieren, bzw. der Code für Queue wurde von Synchronize geklaut.
Wegen des potentiellen Deadlocks wird dort (im Synchronize) geprüft, ob es bereits im Hauptthread ist und dann direkt ausgeführt.
Mir wäre ja lieber gewesen sie reparieren Queue, anstatt 'ne neue Funktion einzuführen.

Am Einfachsten immer nur ForceQueue, denn das geht überall ... sonst wundert man sich im Haupthread, dass Queue dort doch nicht verzögert arbeitet, so wie man es hätte denken können. :wall:

LTE5 17. Dez 2017 14:36

AW: TTask bei FMX startet nicht (Delphi 10.2)
 
Meinst du also, man sollte nur noch TThread.ForceQueue (statt TThread.Queue) verwenden, egal ob ich im Hauptthread oder in einem eigenen TThread oder TTask bin?

himitsu 17. Dez 2017 14:37

AW: TTask bei FMX startet nicht (Delphi 10.2)
 
Jupp.

Es ist einfacher sich auf einwas zu einigen, anstatt immer zu wechseln, so muß man nicht aufpassen was man wann nutzen muß.
In diesem Fall das, was immer und überall funktioniert.

LTE5 17. Dez 2017 14:39

AW: TTask bei FMX startet nicht (Delphi 10.2)
 
ForceQueue schiebt aber trotzdem erst in die Warteschlange und wartet nicht auf das Ende so wie Synchronize oder? Ist gerade etwas verwirrend.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:49 Uhr.
Seite 1 von 2  1 2      

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