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
Seite 1 von 2  1 2      
greenmile

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

Label aktualisieren / TTask

  Alt 12. Jan 2021, 12: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.070 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Label aktualisieren / TTask

  Alt 12. Jan 2021, 13: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, 13: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 14:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

AW: Label aktualisieren / TTask

  Alt 12. Jan 2021, 14: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.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  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, 14: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 15: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, 11: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 11:13 Uhr)
  Mit Zitat antworten Zitat
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.205 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Label aktualisieren / TTask

  Alt 13. Jan 2021, 13:36
Ich hab so ein ähnliches Problem mit einem Timer gelöst. Der Timer feuert jede Sekunde, dann kanst du eine Bedingung testen und dann zB eine Bedingung umschalten.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

AW: Label aktualisieren / TTask

  Alt 13. Jan 2021, 16:06
Wenn das System grundsätzlich nicht mit "derartigen" Messages arbeitet, dann bringt es auch nicht viel die Messages verarbeiten zu wollen, welche es nicht gibt.

Hier mal der Pfad für Android: Thread.Synchronize und Application.OnIdle
Delphi-Quellcode:
procedure TApplication.ProcessMessages; // das aus FMX.Forms.pas
var
  AppService: IFMXApplicationService;
begin
  if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationService, AppService) then
    while AppService.HandleMessage do { loop };
end;

function TPlatformAndroid.HandleMessage: Boolean;
begin
  InternalProcessMessages;
  Result := False;
end;

procedure TPlatformAndroid.InternalProcessMessages;
begin
  CheckSynchronize;
  ProcessOnIdleEvent;
end;
Ich weiß nicht wie Android seine "Events" verwaltet und ob es in Delphi, bzw. im ADK eine API gibt, womit man anstehende Events jetzt verarbeiten kann ... wenn ja, dann sollte Emba Dieses aber besser mal ins ProcessMessages/HandleMessage einfügen.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

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

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

AW: Label aktualisieren / TTask

  Alt 13. Jan 2021, 16:11
Wenn das System grundsätzlich nicht mit "derartigen" Messages arbeitet, dann bringt es auch nicht viel die Messages verarbeiten zu wollen, welche es nicht gibt.

Hier mal der Pfad für Android: Thread.Synchronize und Application.OnIdle
Delphi-Quellcode:
procedure TApplication.ProcessMessages; // das aus FMX.Forms.pas
var
  AppService: IFMXApplicationService;
begin
  if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationService, AppService) then
    while AppService.HandleMessage do { loop };
end;

function TPlatformAndroid.HandleMessage: Boolean;
begin
  InternalProcessMessages;
  Result := False;
end;

procedure TPlatformAndroid.InternalProcessMessages;
begin
  CheckSynchronize;
  ProcessOnIdleEvent;
end;
Heißt auf Deutsch, bringt nix? Wann werden denn die zB Labels gezeichnet? Wenn ich es mit Repaint aufrufe, wird nix neu gezeichnet. Und wenn es keine Nachrichten gibt die verarbeitet werden, wie aktualisiere ich dann von Hand, ohne drauf zu warten, dass es der MainThread irgendwie erledigt?
  Mit Zitat antworten Zitat
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.205 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Label aktualisieren / TTask

  Alt 13. Jan 2021, 21:34
@greenmile: Ich glaube, du musst umdenken. Sowas wie "warten" funktioniert nicht. Du kannst "nachschauen", ob dein Thread schon fertig ist. Dein "Nag-Screen" wäre vielleicht so zu implementieren:


- MainForm anzeigen
- Thread starten + am Mainform ein Panel mit Infos anzeigen
- gleichzeitig einen Timer starten, der jede Sekunde nachschaut, ob der Thread schon fertig ist
- wenn ja, das Panel verstecken und den mainform "freigeben" und den Timer beenden

Hat für mich das Problem "Form schließen wenn Task noch läuft" gut gelöst. Aber ich bin offen für Fortbildung.
  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 16:31 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