Blokierung der Form vermeiden

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Bauer321
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

Beitrag von Bauer321 »

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

MmVisual
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

Beitrag von MmVisual »

In den Schleifen immer wieder ein

Application.Processmessage;

aufrufen.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Dets
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

Beitrag von Dets »

Oder die 'Aktion' in einem eigenen Thread ausführen. :D

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 ...

Bauer321
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

Beitrag von Bauer321 »

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
www.mcpatcher.net | www.hoeper.me

Socke
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

Beitrag von Socke »

Bauer321 hat geschrieben:wie geht das mit einem separaten Thread ? also vll nen winziges beispiel oder so weil mir sagt das so gar nichts
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).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

MmVisual
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

Beitrag von MmVisual »

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.
EleLa - Elektronik Lagerverwaltung - www.elela.de

MAC
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

Beitrag von MAC »

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...

Code: Alles auswählen

Signatur := nil;

Bauer321
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

Beitrag von Bauer321 »

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

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

MmVisual
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

Beitrag von MmVisual »

AAAARRRGGGGG :shock: :shock: :shock: :shock: :shock:


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

MmVisual
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

Beitrag von MmVisual »

Ich hab jetzt ein paar Simies gefunden :wink:
Dateianhänge
poop.gif
poop.gif (391 Bytes) 2664 mal betrachtet
nsojsjkf.gif
nsojsjkf.gif (963 Bytes) 2664 mal betrachtet
glfqnsfk.gif
glfqnsfk.gif (9.72 KiB) 2664 mal betrachtet
fqrajiak.gif
fqrajiak.gif (4.21 KiB) 2664 mal betrachtet
EleLa - Elektronik Lagerverwaltung - www.elela.de

felix96
Beiträge: 287
Registriert: So 29. Nov 2009, 17:44
CPU-Target: 32BitWin+64bitUbunt

Re: Blokierung der Form vermeiden

Beitrag von felix96 »

MmVisual hat geschrieben:Ich hab jetzt ein paar Simies gefunden :wink:
lol
Danke schonmal für eure Antworten
it´s not a bug, it´s a feature!

Benutzeravatar
theo
Beiträge: 10897
Registriert: Mo 11. Sep 2006, 19:01

Re: Blokierung der Form vermeiden

Beitrag von theo »

MmVisual hat geschrieben: SSSSLLLEEEEEPPPP ist das böseste, alllller böööööseste Wort in der Programmierumgebung
Warum?

MmVisual
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

Beitrag von MmVisual »

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.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
theo
Beiträge: 10897
Registriert: Mo 11. Sep 2006, 19:01

Re: Blokierung der Form vermeiden

Beitrag von theo »

MmVisual 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.
Naja, deshalb muss man aber nicht gleich hysterisch werden ;-)
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.

MAC
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

Beitrag von MAC »

die idee mit dem timer ist recht gut.
wobei man sleep(1000);
auch durch

Code: Alles auswählen

x := now;
while x + (1/86400) > now do Application.Processmessages;
ersetzen könnte.
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;
Nur mal so als Anregung wenn man aus irgendwelchen Gründen den Timer nicht verwenden könnte...

Code: Alles auswählen

Signatur := nil;

Antworten