AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Cross-Platform-Entwicklung Delphi TTask bei FMX startet nicht (Delphi 10.2)
Thema durchsuchen
Ansicht
Themen-Optionen

TTask bei FMX startet nicht (Delphi 10.2)

Offene Frage von "himitsu"
Ein Thema von nytaiceman · begonnen am 17. Dez 2017 · letzter Beitrag vom 17. Dez 2017
Antwort Antwort
Seite 1 von 2  1 2      
nytaiceman

Registriert seit: 15. Dez 2005
Ort: Schweiz, Bern
58 Beiträge
 
Delphi XE3 Professional
 
#1

TTask bei FMX startet nicht (Delphi 10.2)

  Alt 17. Dez 2017, 08:38
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?
Miniaturansicht angehängter Grafiken
delphi_10.2_ttask.jpg  
Angehängte Dateien
Dateityp: 7z TTaskTest.7z (52,2 KB, 0x aufgerufen)
Einfach ist nur einfach, wenn Einfach auch einfach ist!
Vermeintlich einfache Workarounds führen irgendwann zu Problemen!
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.116 Beiträge
 
Delphi 12 Athens
 
#2

AW: TTask bei FMX startet nicht (Delphi 10.2)

  Alt 17. Dez 2017, 13:42
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
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#3

AW: TTask bei FMX startet nicht (Delphi 10.2)

  Alt 17. Dez 2017, 13:57
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 ShowMessage('3. After TTask'); ausführen.
$2B or not $2B
  Mit Zitat antworten Zitat
nytaiceman

Registriert seit: 15. Dez 2005
Ort: Schweiz, Bern
58 Beiträge
 
Delphi XE3 Professional
 
#4

AW: TTask bei FMX startet nicht (Delphi 10.2)

  Alt 17. Dez 2017, 14:34
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"
Einfach ist nur einfach, wenn Einfach auch einfach ist!
Vermeintlich einfache Workarounds führen irgendwann zu Problemen!

Geändert von nytaiceman (17. Dez 2017 um 14:36 Uhr) Grund: Code Beispiel vervollständigt
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#5

AW: TTask bei FMX startet nicht (Delphi 10.2)

  Alt 17. Dez 2017, 15:09
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.
$2B or not $2B

Geändert von himitsu (17. Dez 2017 um 15:11 Uhr)
  Mit Zitat antworten Zitat
LTE5

Registriert seit: 13. Nov 2017
355 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#6

AW: TTask bei FMX startet nicht (Delphi 10.2)

  Alt 17. Dez 2017, 15:17
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?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#7

AW: TTask bei FMX startet nicht (Delphi 10.2)

  Alt 17. Dez 2017, 15:29
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.
$2B or not $2B

Geändert von himitsu (17. Dez 2017 um 15:32 Uhr)
  Mit Zitat antworten Zitat
LTE5

Registriert seit: 13. Nov 2017
355 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#8

AW: TTask bei FMX startet nicht (Delphi 10.2)

  Alt 17. Dez 2017, 15:36
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?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#9

AW: TTask bei FMX startet nicht (Delphi 10.2)

  Alt 17. Dez 2017, 15:37
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.
$2B or not $2B
  Mit Zitat antworten Zitat
LTE5

Registriert seit: 13. Nov 2017
355 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#10

AW: TTask bei FMX startet nicht (Delphi 10.2)

  Alt 17. Dez 2017, 15:39
ForceQueue schiebt aber trotzdem erst in die Warteschlange und wartet nicht auf das Ende so wie Synchronize oder? Ist gerade etwas verwirrend.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:05 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