![]() |
VCL-Form aktualisieren obwohl Maschine ausgelastet ist
Liebe Wissende,
ich bin leider noch Anfänger. Mit einem VCL-Form habe ich das Problem, dass, wenn eine Prozedur gestartet wird, die etwas länger dauert, und ich vorher z.b. ein TLabel.Caption beschreibe, er mir diese TLable.Caption nicht anzeigt. Gibt es irgendwelche Befehle um das Label, das ja gesetzt wurde auch anzuzeigen? Beispiel: ich habe eine Prozedur auf einem Button, die lange ausgeführt wird.
Delphi-Quellcode:
... und hier geht es noch enldos weiter. Die Prozedur dauert ca 2 Minuten.
procedure TAuswExcelll.BuExGrClick(Sender: TObject);
var Artikel, Wznr, inter, Dateiname : String; i,j,a,ii,gefunden,letztezeile,summe, zeile : integer; begin LblAchtung.Caption:='Bitte warten!'; // Noch ein Array mit Group by Wznr, Summe aus Intervall, unsichtbar. Setlength(Tab,1000,4); for i:=0 to 999 do begin //Array Feldbreite bestimmen for j:=0 to 3 do begin Setlength(Tab[i,j], 10); end; end; for i:=0 to 999 do begin //Array leer machen for j:=0 to 3 do begin Tab[i,j]:=''; end; end; der LblAchtung.Caption:='Bitte warten!'; wird zur laufzeit auf dem Form aber garnicht angezeigt. Ich hoffe ich habe mich verständlich ausgedrückt. |
AW: VCL-Form aktualisieren obwohl Maschine ausgelastet ist
Hey!
Baue in deine Schleife
Delphi-Quellcode:
ein.
application.ProcessMessages;
Diese Prozedur zwingt das System zur Aktualisierung. Alternativ baue sie vor die Schleife ein (Ressourcen sparen) MfG, Noobmaster |
AW: VCL-Form aktualisieren obwohl Maschine ausgelastet ist
Das ProcessMessages wäre sinnvoll, wenn zwischendrin noch mehr aktualisiert werden soll, kann aber ggf. doofe Nebeneffekte haben (z.B. ganze andere große lange Verarbeitungen auslösen, wenn man deren Auslöser nicht explizit deaktiviert hat.) Die unmittelbare Lösung, die dem Problem am angemessensten wäre, ist:
Delphi-Quellcode:
procedure TAuswExcelll.BuExGrClick(Sender: TObject);
var Artikel, Wznr, inter, Dateiname : String; i,j,a,ii,gefunden,letztezeile,summe, zeile : integer; begin LblAchtung.Caption:='Bitte warten!'; LblAchtung.Repaint; // <-------------------- !!!! . . |
AW: VCL-Form aktualisieren obwohl Maschine ausgelastet ist
Und nur der Vollständigkeit halber: man könnte auch die lange dauernde Operation in einen Thread auslagern, welcher dann synchronisiert die VCL-Controls aktualisiert. Allerdings ist das nicht unbedingt anfängerfreundlich.
|
AW: VCL-Form aktualisieren obwohl Maschine ausgelastet ist
Application.ProcessMessages birgt aber diverse Gefahren, man merke etwa, daß Dein OnClick-Handler den Button nicht für den Zeitraum der Aktion disabled, so daß ein ProcessMessages etwa bewirken würde, daß der Nutzer die Berechnung ein zweites Mal starten kann, bevor die erste zuende gelaufen ist (weil er den Button-Click "processed").
Anders gesagt: die einzige sinnvolle Variante ist, rechenintensives in Threads auszulagern. LblAchtung.Refresh und Application.ProcessMessages sind ein Workaround, der klappen mag, wenn die Form kaum was kann und die einzigen Alternativ-Actions disabled werden, aber schön ist das trotzdem nicht. |
AW: VCL-Form aktualisieren obwohl Maschine ausgelastet ist
Zitat:
Man kann übrigens auch ein Refresh (der Form) regelmäßig aufrufen, bzw. die entsprechenden Controls refreshen/repainten. |
AW: VCL-Form aktualisieren obwohl Maschine ausgelastet ist
Das hatten wir bereits in #3 (*seufz*). Allerdings reagiert das Formular zwischen 2 Aufrufen auch anderweitig nicht (verschieben etc.).
|
AW: VCL-Form aktualisieren obwohl Maschine ausgelastet ist
Zitat:
- in Threads auslagen (und die VCL-Aufrufe synchronisieren) - nur das Repainten, was man benötigt (sonst reagiert aber nichts) - Application.ProcessMessages und die entsprechenden Funktionen disablen (falls nötig), wärend der Laufzeit - nur Application.ProcessMessages und mit den Gefahren leben - die Funktion in kleine Einheiten aufteilen und via Timer abarbeiten Auswahlmöglichkeiten gibt es zu Genüge. |
AW: VCL-Form aktualisieren obwohl Maschine ausgelastet ist
Aber auch wenn man mit Threads arbeitet, sollte man die Steuerelemente deaktivieren, sonst kann der Thread mehr mals gestartet werden. Nichts desto trotz halte ich Threads für die sauberere Lösung. Denn arbeitet man mit Processmessages, wird jedes mal die Verarbeitung unterbrochen, wenn Nachrichten abgearbeitet werden. Verschiebt man das Fenster zum Beispiel oder muss es häufig aktualisiert werden und stehen deshalb viele Nachrichten an, wird gar nichts gemacht, weil erst mal die ganzen anstehenden Nachrichten abgearbeitet werden.
|
AW: VCL-Form aktualisieren obwohl Maschine ausgelastet ist
Gegen mehrmaliges Aktivieren hilft ein einfaches
Delphi-Quellcode:
Wobei..
Procedure TMyForm.myButtonClick(Sender : TObject);
Begin If myButton.Tag=0 then try myButton.Tag := 1; // Und hier was extrem lahmes mit Application.ProcessMessages zwischendurch finally myButton.Tag := 0; end end;
Delphi-Quellcode:
ist irgendwie ... naheliegender :mrgreen:
myButton.Enabled := False
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz