AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Label aktualisieren / TTask

Ein Thema von greenmile · begonnen am 12. Jan 2021 · letzter Beitrag vom 19. Jan 2021
Antwort Antwort
greenmile

Registriert seit: 17. Apr 2003
1.107 Beiträge
 
Delphi 10.3 Rio
 
#1

Label aktualisieren / TTask

  Alt 12. Jan 2021, 11:08
Hallo,

ich bin ja aktuell dabei, mein Android Projekt von XE8 auf XE 10.3.3 umzustellen. Während in der 8 noch intensiv mit Application.Processmessages gearbeitet wurde (ja, war und ist böse, aber der Zweck heiligt die Mittel) funktioniert das ja in 10.3.3 nicht so wie bisher. Ich habe zB TAniIndicator. Wenn nun in der App etwas Rechenintensives passiert oder die App einfach mal auf was warten muss, dann wurde der TAniIndicator bisher mit Processmessages erfolgreich aktualisiert. Das klappt nun nicht mehr und sieht blöd aus, so als wenn alles hängt. Also versuche ich es so:

Code:
procedure ...UpdateComponents;
begin
  ...
  If (progPlsWait) then progPlsWait.Repaint;
  ...
end;
Habe dann versucht, über einen HG-Thread die Proc dauernd zu aktualisieren:

Code:
   CompUpdateTask := TTask.Create(
     procedure
     begin
       Sleep(50);
       TThread.Synchronize(TThread.Current,
         procedure
         begin
           UpdateComponents;
         end);
     end);
   CompUpdateTask.Start;
... und, wenn die Berechnung durch ist, das ganze freizugeben

Code:
  CompUpdateTask.Cancel;
  FreeAndNil(CompUpdateTask);
So, der Profi lacht, aber das funktioniert nicht, TAniIndicator wird nicht aktualisiert. Was mache ich falsch? Durchläuft CompUpdateTask nur einmal und ist danach tot, wie ein Thread auch?
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.062 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Label aktualisieren / TTask

  Alt 12. Jan 2021, 12:08
Zitat:
Durchläuft CompUpdateTask nur einmal und ist danach tot, wie ein Thread auch
Dir fehlt ja auch die Schleife.
Stelle dir einfach vor, die anonyme Funktion wäre das Execute einer klassischen TThread-Instanz.
Dann startet der Thread, wartet 50 Millisekunden und ruft einmal (!) TThread.Synchronize auf.
  Mit Zitat antworten Zitat
greenmile

Registriert seit: 17. Apr 2003
1.107 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Label aktualisieren / TTask

  Alt 12. Jan 2021, 12:56
Ah, ok, quasi "while not terminated"? Wenn ich es recht verstehe, muss ich "CheckCanceled" aufrufen, das wirft eine Exception, wenn abgebrochen werden soll.
Passt das so? Die While Bedingung ist echt dumm.

Code:
   CompUpdateTask := TTask.Create(
     procedure
     begin
       While (1=1) do begin
         CompUpdateTask.CheckCanceled;

         Sleep(500);
         TThread.Synchronize(TThread.Current,
           procedure
           begin
             UpdateComponents;
           end);
        End;
     end);
   CompUpdateTask.Start;

Geändert von greenmile (12. Jan 2021 um 13:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Label aktualisieren / TTask

  Alt 12. Jan 2021, 13:48
Und "eventuell" aufpassen, dass
Delphi-Quellcode:
CompUpdateTask.Cancel;
FreeAndNil(CompUpdateTask);
nicht im Hauptthread ausgeführt werden (vor allem niemals innerhalb von UpdateComponents),
denn wenn Cancel oder Free warten, während das Synchronize hängt, dann hast einen Deadlock.

Tipp: Auch in das Synchronize am Anfang ein CheckCanceled rein.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
greenmile

Registriert seit: 17. Apr 2003
1.107 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Label aktualisieren / TTask

  Alt 12. Jan 2021, 13:55
Und "eventuell" aufpassen, dass
Delphi-Quellcode:
CompUpdateTask.Cancel;
FreeAndNil(CompUpdateTask);
nicht im Hauptthread ausgeführt werden (vor allem niemals innerhalb von UpdateComponents),
denn wenn Cancel oder Free warten, während das Synchronize hängt, dann hast einen Deadlock.

Tipp: Auch in das Synchronize am Anfang ein CheckCanceled rein.
Danke für den Tipp, aber ich muss doch vom Haupthread aus Cancel setzen, damit der TTask abgebrochen und beendet wird.
FreeAndNil war übrigens auch blöd, ein := NIL besser.

Nachtrag: Funktioniert übrigens nicht, TAniIndicator wird, genau wie Labels, nicht aktualisiert; repaint reicht wohl nicht. Die 'Arbeit' kann ich auch nicht auslagern, ich muss zB einen Browser aufrufen und der läuft im Hauptthread. Während ich auf den Warte, tut sich unter 10.3.3 dann mal nix, auch kein drehendes 'Bitte warten' Icon.

Irgendwie war das mit Processmessages einfacher. Zumindest hat sich was getan für den User.

Geändert von greenmile (12. Jan 2021 um 14:13 Uhr)
  Mit Zitat antworten Zitat
greenmile

Registriert seit: 17. Apr 2003
1.107 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: Label aktualisieren / TTask

  Alt 13. Jan 2021, 10:05
Ich verzweifel noch. Ich benötige ein funktionierendes Delay, also um etwas bei Bedarf künstlich zu verzögern. Nehmen wir als Beispiel eine Testversion: Wenn es sich bei der App um eine Testversion handelt, dann soll 10 Sekunden gewartet werden (Delay 10), ansonsten direkt weitergemacht werden. Ich bekomme es einfach nicht hin. Es wird zwar gewartet, in der Wartezeit werden aber keine Nachrichten verarbeitet, ich kann also kein Warte-Progress anzeigen.

Unter Windows ganz einfach:

Code:
  Ende := GetTickCount+mSek;

  While (Ende>GetTickCount) do begin
    Sleep(5);
    Application.ProcessMessages;
  end;
Im Android funktioniert zwar die Wartezeit (klar, was soll auch passieren), es wird aber nichts verarbeitet, da Processmessages nicht funktioniert. Habe es auch schon mit einem Thread versucht in der Hoffnung, dass während 'WaitFor' Nachrichten wie Repaint verarbeitet werden ... Geht aber auch nicht. Obwohl ich Label.Repaint aufrufe, sehe ich die Änderungen auf dem Handy nicht. Beispiel:

Code:
Label1.Text := 'Hallo';
Delay(1000);
Label1.Text := 'Welt';
Delay(1000);
Label1.Text := 'Bin';
Delay(1000);
Label1.Text := 'Fertig';
Ist ein nonsens Code. Im Ergebnis ist entweder nichts sichtbar. Oder nur 'Fertig', selbst wenn ich im Delay "Label1.Repaint" aufrufe. Mache ich das unter Windows, dann steht dort im Sekundentakt 'Hallo' / 'Welt' / 'Bin' / 'Fertig'. Selbst mit einem Timer kann ich es nicht lösen, weil ich ja auch auf seine Beendigung warten muss.

Bin ich wirklich der einzige, der sowas braucht?

Geändert von greenmile (13. Jan 2021 um 10:13 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


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:50 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