Blokierung der Form vermeiden
-
- Beiträge: 465
- Registriert: Sa 21. Aug 2010, 21:30
- OS, Lazarus, FPC: Windows 7 Ultimate (L 1.2.2 FPC 2.6.4 32-bit)
- CPU-Target: 64-Bit
- Wohnort: nahe Bremen
- Kontaktdaten:
Blokierung der Form vermeiden
Also wenn man auf einen Button klick wird ja alles sol lange "blockiert" bis die aktion beendet ist. lässt sich das vermeiden?
www.mcpatcher.net | www.hoeper.me
-
- Beiträge: 1581
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
- CPU-Target: 32/64Bit
Re: Blokierung der Form vermeiden
In den Schleifen immer wieder ein
Application.Processmessage;
aufrufen.
Application.Processmessage;
aufrufen.
EleLa - Elektronik Lagerverwaltung - www.elela.de
-
- Beiträge: 61
- Registriert: Di 11. Sep 2007, 16:59
- OS, Lazarus, FPC: Ubuntu Maverick (L 0.9.28.2-10, FPC 2.4.0)
- CPU-Target: 32Bit
- Wohnort: Lage
- Kontaktdaten:
Re: Blokierung der Form vermeiden
Oder die 'Aktion' in einem eigenen Thread ausführen.
Dass das Programm blockiert erscheint liegt daran, dass neben dem eigentlichen Aktionscode auch noch die Messageloop (unsichtbar für den Lazarus-Programmierer) abgearbeitet wird, in der Nachrichten ausgewertet werden, ob sich z.B. Formulare irgendwo neu malen müssen. Wenn jetzt deine Aktion länger läuft, dann landen zwar die Nachrichten in der Messageloop, werden aber nicht abgearbeitet, so dass dann das Neuzeichnen nicht ausgeführt wird und damit ein Formular 'tot' erscheint. Mit Application.ProcessMessages sagt man seinem Programm: guck mal in die Messageloop und wenn Nachrichten drin sind, dann arbeite sie ab. Allerdings sollte man darauf achten, dass man Application.ProcessMessages nicht zu oft aufruft, weil dann die 'Aktion' stark verlangsamt wird und auch nicht zu selten, weil dann das Formular nur sehr verzögert auf Nachrichten reagiert.
Bei einem separaten Thread gibt es nichts zu beachten, allerdings ist der auch schwieriger zu programmieren.
greetz, Dets ...

Dass das Programm blockiert erscheint liegt daran, dass neben dem eigentlichen Aktionscode auch noch die Messageloop (unsichtbar für den Lazarus-Programmierer) abgearbeitet wird, in der Nachrichten ausgewertet werden, ob sich z.B. Formulare irgendwo neu malen müssen. Wenn jetzt deine Aktion länger läuft, dann landen zwar die Nachrichten in der Messageloop, werden aber nicht abgearbeitet, so dass dann das Neuzeichnen nicht ausgeführt wird und damit ein Formular 'tot' erscheint. Mit Application.ProcessMessages sagt man seinem Programm: guck mal in die Messageloop und wenn Nachrichten drin sind, dann arbeite sie ab. Allerdings sollte man darauf achten, dass man Application.ProcessMessages nicht zu oft aufruft, weil dann die 'Aktion' stark verlangsamt wird und auch nicht zu selten, weil dann das Formular nur sehr verzögert auf Nachrichten reagiert.
Bei einem separaten Thread gibt es nichts zu beachten, allerdings ist der auch schwieriger zu programmieren.
greetz, Dets ...
-
- Beiträge: 465
- Registriert: Sa 21. Aug 2010, 21:30
- OS, Lazarus, FPC: Windows 7 Ultimate (L 1.2.2 FPC 2.6.4 32-bit)
- CPU-Target: 64-Bit
- Wohnort: nahe Bremen
- Kontaktdaten:
Re: Blokierung der Form vermeiden
das mit dem application.processmassages oder so... bringt schon etwas aber ich bin noch nicht wirklich zufrieden^^
wie geht das mit einem separaten Thread ? also vll nen winziges beispiel oder so weil mir sagt das so gar nichts
wie geht das mit einem separaten Thread ? also vll nen winziges beispiel oder so weil mir sagt das so gar nichts
www.mcpatcher.net | www.hoeper.me
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Blokierung der Form vermeiden
Suche mal bitte im Internet oder auch hier im Forum danach. Das ganze läuft ähnlich wie in Delphi ab. Es gibt nur minimale platformabhängige Unterschiede, die bei einem durchdachten Design sowieso nicht zum Tragen kommen).Bauer321 hat geschrieben:wie geht das mit einem separaten Thread ? also vll nen winziges beispiel oder so weil mir sagt das so gar nichts
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- Beiträge: 1581
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
- CPU-Target: 32/64Bit
Re: Blokierung der Form vermeiden
Hast Du Datenbank-Aktionen drin wo mehrere Records bearbeitet werden/Liste durchlaufen?
Dann hilft
Query.DisableControls;
...
Query.EnableControls;
Oder sonstige "Zeitfresser" suchen und umprogrammieren. Oder mal hier die Routine einstellen.
Komplizierte Funktionen könnte man auch "Scheibchenweise" mit Timer-Aufrufe abarbeiten.
Threads sollten nur als letzter Ausweg genommen werden, denn damit bekommt man das neue Problem der Synchronität mit der Applikation.
Dann hilft
Query.DisableControls;
...
Query.EnableControls;
Oder sonstige "Zeitfresser" suchen und umprogrammieren. Oder mal hier die Routine einstellen.
Komplizierte Funktionen könnte man auch "Scheibchenweise" mit Timer-Aufrufe abarbeiten.
Threads sollten nur als letzter Ausweg genommen werden, denn damit bekommt man das neue Problem der Synchronität mit der Applikation.
EleLa - Elektronik Lagerverwaltung - www.elela.de
-
- Beiträge: 770
- Registriert: Sa 21. Feb 2009, 13:46
- OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
- CPU-Target: 32Bit
Re: Blokierung der Form vermeiden
Wie schon bereits erwähnt sollten threads nur als letzten ausweg benutzt werden.
Was willst du denn genau machen? Vielleicht kann man den Code anders umschreiben das er schneller läuft...
Normalerweise ist application.processmassages in einer Schleife schon ziemlich ausreichend...
Was willst du denn genau machen? Vielleicht kann man den Code anders umschreiben das er schneller läuft...
Normalerweise ist application.processmassages in einer Schleife schon ziemlich ausreichend...
Code: Alles auswählen
Signatur := nil;
-
- Beiträge: 465
- Registriert: Sa 21. Aug 2010, 21:30
- OS, Lazarus, FPC: Windows 7 Ultimate (L 1.2.2 FPC 2.6.4 32-bit)
- CPU-Target: 64-Bit
- Wohnort: nahe Bremen
- Kontaktdaten:
Re: Blokierung der Form vermeiden
also das ist einfach sowas wie ne stopuhr mit gettickcount
also im moment siehts einfach so aus sprich er macht das 30 sec und trägts ion nen memo ein
also im moment siehts einfach so aus sprich er macht das 30 sec und trägts ion nen memo ein
Code: Alles auswählen
procedure test();
begin
time:=GetTickCount;
repeat
sleep(1000);
stime := round((gettickcount-time)/1000);
Form1.Memo2.Lines.Add(inttostr(stime));
Application.Processmessages
until stime > 30;
end;
www.mcpatcher.net | www.hoeper.me
-
- Beiträge: 1581
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
- CPU-Target: 32/64Bit
Re: Blokierung der Form vermeiden
AAAARRRGGGGG
SSSSLLLEEEEEPPPP ist das böseste, alllller böööööseste Wort in der Programmierumgebung So ein Smilie gibt es gar nicht was man jetz hier einfügen sollte.
Mach es besser so:





SSSSLLLEEEEEPPPP ist das böseste, alllller böööööseste Wort in der Programmierumgebung So ein Smilie gibt es gar nicht was man jetz hier einfügen sollte.
Mach es besser so:
Code: Alles auswählen
Var time: DWORD;
procedure Form1.Test()
Begin
time:=GetTickCount;
Timer1.Enable := True;
End;
procedure Form1.Timer1OnTimer();
begin
stime := round((gettickcount-time)/1000);
Form1.Memo2.Lines.Add(inttostr(stime));
if stime > 30 Then
Timer1.Enable := False;
End;
Zuletzt geändert von MmVisual am Sa 11. Dez 2010, 21:22, insgesamt 1-mal geändert.
EleLa - Elektronik Lagerverwaltung - www.elela.de
-
- Beiträge: 1581
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
- CPU-Target: 32/64Bit
Re: Blokierung der Form vermeiden
Ich hab jetzt ein paar Simies gefunden 

- Dateianhänge
-
- poop.gif (391 Bytes) 2664 mal betrachtet
-
- nsojsjkf.gif (963 Bytes) 2664 mal betrachtet
-
- glfqnsfk.gif (9.72 KiB) 2664 mal betrachtet
-
- fqrajiak.gif (4.21 KiB) 2664 mal betrachtet
EleLa - Elektronik Lagerverwaltung - www.elela.de
Re: Blokierung der Form vermeiden
lolMmVisual hat geschrieben:Ich hab jetzt ein paar Simies gefunden
Danke schonmal für eure Antworten
it´s not a bug, it´s a feature!
it´s not a bug, it´s a feature!
Re: Blokierung der Form vermeiden
Warum?MmVisual hat geschrieben: SSSSLLLEEEEEPPPP ist das böseste, alllller böööööseste Wort in der Programmierumgebung
-
- Beiträge: 1581
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
- CPU-Target: 32/64Bit
Re: Blokierung der Form vermeiden
Das weißt Du doch sicher auch. Das steht die gesammte Applikation, die ist wie eingefrohren. Nichts mehr bedienbar.
Selbst wenn man alle Sekunde das Application.Processmessage drin hat, kann man die nur noch im "Sekundentakt" bedienen.
Das kann doch wohl niemals im Sinne des Erfinders sein.
Um das ordentlich zu lösen hab ich ja schon das Beispiel mit dem Timer gezeigt.
Abgesehen davon wäre es vielleicht besser man würde anstatt dem GetTickCount ein Now verwenden und mit der aktuellen Systemzeit rechnen (TDateTime).
Der Wert von GetTickCount Überläuft nach ca. 49 Tage, dafür kann man mit Now nur die richtige Zeit berechnen solange niemand die Systemuhrzeit verstellt.
Die andere Alternative, man Incrementiert bei jedem Timer-Aufruf eine Zahl bis 30 und der Timer ist mit einem Intervall von 1000 parametriert. Wenn der Timer mal später kommen sollte, weil Windows gerade sehr beschäftigt ist, dann dehnt sich die ein oder andere Sekunde, das ist mit der NOW Abfrage nicht möglich, bzw. korrigiert sich automatisch.
Also, es gibt drei Wege, die mit Timer tun mit den jeweiligen Vor- und Nachteilen.
Selbst wenn man alle Sekunde das Application.Processmessage drin hat, kann man die nur noch im "Sekundentakt" bedienen.
Das kann doch wohl niemals im Sinne des Erfinders sein.
Um das ordentlich zu lösen hab ich ja schon das Beispiel mit dem Timer gezeigt.
Abgesehen davon wäre es vielleicht besser man würde anstatt dem GetTickCount ein Now verwenden und mit der aktuellen Systemzeit rechnen (TDateTime).
Der Wert von GetTickCount Überläuft nach ca. 49 Tage, dafür kann man mit Now nur die richtige Zeit berechnen solange niemand die Systemuhrzeit verstellt.
Die andere Alternative, man Incrementiert bei jedem Timer-Aufruf eine Zahl bis 30 und der Timer ist mit einem Intervall von 1000 parametriert. Wenn der Timer mal später kommen sollte, weil Windows gerade sehr beschäftigt ist, dann dehnt sich die ein oder andere Sekunde, das ist mit der NOW Abfrage nicht möglich, bzw. korrigiert sich automatisch.
Also, es gibt drei Wege, die mit Timer tun mit den jeweiligen Vor- und Nachteilen.
EleLa - Elektronik Lagerverwaltung - www.elela.de
Re: Blokierung der Form vermeiden
Naja, deshalb muss man aber nicht gleich hysterisch werdenMmVisual hat geschrieben:Das weißt Du doch sicher auch. Das steht die gesammte Applikation, die ist wie eingefrohren. Nichts mehr bedienbar.
Selbst wenn man alle Sekunde das Application.Processmessage drin hat, kann man die nur noch im "Sekundentakt" bedienen.

Von einem Sleep(100) merkst du beispielsweise nicht viel. Es fragt sich natürlich ob und wann es sinnvoll ist, aber soo schlimm ist das nicht.
-
- Beiträge: 770
- Registriert: Sa 21. Feb 2009, 13:46
- OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
- CPU-Target: 32Bit
Re: Blokierung der Form vermeiden
die idee mit dem timer ist recht gut.
wobei man sleep(1000);
auch durch
ersetzen könnte.
Wenn dass 100% auslastung gibt dann sowas
Nur mal so als Anregung wenn man aus irgendwelchen Gründen den Timer nicht verwenden könnte...
wobei man sleep(1000);
auch durch
Code: Alles auswählen
x := now;
while x + (1/86400) > now do Application.Processmessages;
Wenn dass 100% auslastung gibt dann sowas
Code: Alles auswählen
x := now;
while x + (1/86400) > now do ;
begin
sleep(0.000000001) // Und ja nicht länger sonst Smiley 3 :mrgreen:
Application.Processmessages
end;
Code: Alles auswählen
Signatur := nil;