Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   IOS UniDac While Schleife mit Progressbar (https://www.delphipraxis.net/212492-ios-unidac-while-schleife-mit-progressbar.html)

oakley 17. Feb 2023 16:07

IOS UniDac While Schleife mit Progressbar
 
Hallo zusammen,

ich lese unter IOS via Unidac eine MySql Tabelle aus.
Dazu habe ich einen Fortschrittsbalken, der mit jedem Durchlauf der While Schleife weiter gefüllt werden soll.
Problem ist dass der Balken am Ende der Schleife direkt auf 100% springt und sich nicht "gemächlich" füllt obwohl der Vorgang einige Sekunden dauert.
Die Progressbar wird dynamisch erzeugt.

Delphi-Quellcode:
procedure TSyncThread.Execute;
var
  sqlstring : String;
begin
   SYNCQUERY.Close;
   SYNCQUERY.SQL.Text := 'SELECT * from table';
   SYNCQUERY.Execute;

   while not SNYCQUERY.Eof do
   begin
     //hier schreibe ich Daten aus der Tabelle in eine TStringlist
     TSyncThread.Queue(nil,
     procedure
     begin
       (Syncform.SB1.FindComponent('Progressbar1') as TProgressbar).value := (Syncform.SB1.FindComponent('Progressbar1') as TProgressbar).value + 1;
     end);    
     SYNCQUERY.Next;
   end;
LG

Mirko

AuronTLG 17. Feb 2023 16:56

AW: IOS UniDac While Schleife mit Progressbar
 
Sieht das so aus, dass er auf 0 % steht und dann nach einer kurzen Weile plötzlich direkt auf 100 % hochgeht?

Auf IOS gibt es nämlich das Problem, dass optische Änderungen außerhalb des Mainthreads nicht direkt eine Aktualisierung der Optik auslösen.
D.h. in dem Fall würde der Ladebalken ganz normal angepasst, jedoch aktualisierte sich die Optik der Maske erst ganz am Ende, so dass der Ladebalken optisch sofort von 0 % auf 100 % ginge.
Ich habe auf IOS tatsächlich noch nie mit einem Ladebalken herumgespielt, aber das könnte passen, da du das ja in einem eigenen Thread machst.

Wenn du austesten willst, ob das der Fall ist, müsstest du deine Funktion mal im Mainthread ausführen. Ist meine Theorie korrekt, müsste es auf diese Weise so aussehen wie erwartet.

Sollte es dieses Problem sein gibt es zwar einen Trick, aber der könnte mit einem Ladebalken problematisch sein:

Man kann ein optisches Update aus einem Thread heraus dadurch erzwingen, dass man sich z.B. ein sichtbares TMemo mit Höhe 0 irgendwo auf die Maske legt und sich dann eine Methode erstellt, welche zuerst ein Memo.SetFocus und dann ein Memo.Repaint. Diese Methode ruft man dann direkt aus dem Thread auf, wenn man ein optisches Update erzwingen will.
Das Problem daran ist, dass dieser Workaround einen leichten Lag hat.

Ich habe das Problem immer dann, wenn ich nach einem erfolgreichen NFC Scan irgendwie die Optik ändere. Dafür ist der oben beschriebene Workaround ausreichend, da ich das nur ein einziges Mal nach meiner Optikanpassung machen muss.
In deinem Fall wäre das jedoch problematisch, da der Ladebalken ja eigentlich flüssig volllaufen soll.

himitsu 17. Feb 2023 18:11

AW: IOS UniDac While Schleife mit Progressbar
 
WAS dauert hier so lange?

Das Schreiben in die Stringlist kann doch nicht so lange dauern.
Ich würde den Fehler eher beim
Delphi-Quellcode:
SYNCQUERY.Execute;
suchen.



Gibt es vorher auch irgendwo Zeit, damit die Queue abgearbeitet wird?
Also nicht dass es wirklich erst ganz am Ende alles ausgeführt wird.
Was sagt der Debugger?

Refresh/Repaint auf die Komponente oder Form?
Oder z.B. Ausgabe in ein Label, ob es dort schneller reagiert.


hmmmmmmmmm :gruebel:
Zitat:

Delphi-Quellcode:
(Syncform.SB1.FindComponent('Progressbar1') as TProgressbar).value := (Syncform.SB1.FindComponent('Progressbar1') as TProgressbar).value + 1;

Delphi-Quellcode:
(Syncform.SB1.FindComponent('Progressbar1') as TProgressbar).StepIt;


[edit]
Ohhh, ist es nicht ein Bug, dass es im FMX sowas nicht gibt?

oakley 17. Feb 2023 22:12

AW: IOS UniDac While Schleife mit Progressbar
 
Also ich mache an anderer Stelle in der App einen Download mit Fortschrittsbalken via IndyFtp.
Funktioniert ohne Probleme und wird auch per Thread sauber Synchronisiert.
Ich habe eher das Unidac in Verdacht, denn es scheint Probleme mit der While Schleife zu geben.
Wenn ich eine einfache For Schleife nehme funcktioniert es einwandfrei.

LG

Mirko

hoika 18. Feb 2023 00:02

AW: IOS UniDac While Schleife mit Progressbar
 
Hallo,
müsste es nicht Query.Open sein?

EmWieMichael 18. Feb 2023 07:04

AW: IOS UniDac While Schleife mit Progressbar
 
Zitat:

Zitat von hoika (Beitrag 1518851)
Hallo,
müsste es nicht Query.Open sein?

Execute ruft intern Open auf, wenn es sich um ein SELECT handelt.

Keine Ahnung ob´s hilft, aber ich würde vor einem .EoF stets ein .First setzen.

himitsu 18. Feb 2023 08:33

AW: IOS UniDac While Schleife mit Progressbar
 
Nach dem Open ist es schon auf First.


"Normal" sollte Execute/Open ALLE Daten sofort laden und erst danach läuft die Schleife da drüber, was jetzt schön im RAM liegt.

Delphi.Narium 19. Feb 2023 11:55

AW: IOS UniDac While Schleife mit Progressbar
 
Vor der While-Schleife würd' ich ja zuerst mal die Position der Progressbar auf 0 setzen und das Maximum auf die Anzahl der Datensätze.
Zitat:

Die Progressbar wird dynamisch erzeugt.
Wann denn? Wie sind denn die Standardwerte der entsprechenden Attribute der Progressbar?

Ist sie vielleicht deshalb so schnell auf 100, weil das Maximum weit unterhalb der Anzahl der Datensätze der Abfrage liegt?

Bei z. B. 'nem Maximum der Progressbar von 100 und 10.000 Datensätze, ist die Position des Maximums per Value + 1 halt bereits nach einem Prozent der zu verarbeitenden Datenmenge erreicht, siehe FMX.StdCtrls.TProgressBar.Value.

Standard für Min = 0, für Max = 100, Value gibt damit die Verarbeitungsposition in Prozent an. Bei Value + 1 wären dann nach 100 Schleifendurchläufen 100% erreicht.

Wenn's um Prozentangaben gehen soll, könnte (theoretisch) sowas funktionieren:

Delphi-Quellcode:
(Syncform.SB1.FindComponent('Progressbar1') as TProgressbar).value := SYNCQUERY.RecNo * 100 div SYNCQUERY.RecordCount;

oakley 20. Feb 2023 08:39

AW: IOS UniDac While Schleife mit Progressbar
 
Ja schön blöd ich habe vergessen das Max der Progressbar gleich RecordCount zu setzen.
Danke das war das Problem und jetzt funktioniert es auch.

LG

Mirko


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:09 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