Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   TApplication.OnIdle Event (https://www.delphipraxis.net/205156-tapplication-onidle-event.html)

freimatz 6. Aug 2020 17:43

TApplication.OnIdle Event
 
Hallo zusammen,
kann mir wer nähere Infos geben, wann denn das TApplication.OnIdle Event kommt.
Mit google finde ich das: http://docs.embarcadero.com/products...on_OnIdle.html

Was heisst "An application is idle when it is not processing code.".

Wenn ich hier eine App starte, dann erscheint zuerst ein Splash-Screen und bin ich schon im OnIdle bevor überhaupt das Hauptfenster offen ist. Da komme ich dann immer wieder vorbei. ("Done" wird nicht verändert, ist auf True)
Kann es sein, dass es an einem Timer liegt, der regelmäßig kommt?

Wenn ich im Callstack schaue, dann komme ich daher:
Delphi-Quellcode:
procedure TApplication.HandleMessage;
var
  Msg: TMsg;
begin
  if not ProcessMessage(Msg) then Idle(Msg);
end;
Könnte man vereinfacht sagen, OnIdle kommt sobald alle Windows-Botschaften abgearbeitet sind?

TurboMagic 6. Aug 2020 20:39

AW: TApplication.OnIdle Event
 
So wie ich es verstehe wird zumindest unter Windows OnIdle immer dann aufgerufen, wenn keine Botschaften zu verarbeiten sind. Schubst du also eifrig die Maus oder klimpert mit der Tastatur, wird es kaum zum Zug kommen.

Michael II 7. Aug 2020 01:33

AW: TApplication.OnIdle Event
 
Zitat:

Zitat von TurboMagic (Beitrag 1471310)
Schubst du also eifrig die Maus..., wird es kaum zum Zug kommen.

Für den von freimatz beschriebenen Fall done=true ("OnIdle is called only once, as the application transitions into an idle state."): Das Gegenteil ist der Fall. Windows sendet dann haufenweise WM_MOUSEMOVEs an deine App, was zu haufenweise zusätzlichen "OnIdles" führt.

Zitat:

Zitat von freimatz (Beitrag 1471307)
Kann es sein, dass es an einem Timer liegt, der regelmäßig kommt?

Wenn du wissen willst nach welchen WM_xxx Meldungen dein Idle(.) ausgelöst wird, dann könntest du die WM_xxx zwischen zwei Idles ja abspeichern (zum Beispiel via TApplicationEvents OnMessage).

Du schreibst nicht, was du in deinem OnIdle Handler tust. Eventuell könntest du die Dinge woanders tun (?).

freimatz 7. Aug 2020 11:10

AW: TApplication.OnIdle Event
 
Hallo,
Danke für die Hinweise. Dann ist es mir so ungefähr klar wie das OnIdle funktioniert. Es geht dann wohl nur um Windows-Botschaften. Wenn im Hintergrund noch ein Thread vor sich hinwerkelt wird das nicht berücksichtigt - oder? Dann wäre die Doku etwas irreführend.

Ich wollte das was ich in OnIdle machen will, nicht gleich woanders machen sondern zuerst mal verstehen.

In meinem Anwendungsfall gibt es auch niemand der die Maus schubst oder Tasten drückt. In dem Fall hat man eine TAction ausgelöst und unsere Testautomatisierung will wissen wenn sie weiter machen kann.

TurboMagic 7. Aug 2020 11:23

AW: TApplication.OnIdle Event
 
OnIdle ist in der Tat unabhängig von irgendwelchen Threads die du erzeugt hast.

QuickAndDirty 7. Aug 2020 16:16

AW: TApplication.OnIdle Event
 
Zitat:

Zitat von TurboMagic (Beitrag 1471332)
OnIdle ist in der Tat unabhängig von irgendwelchen Threads die du erzeugt hast.

Naja, Es wird ja geraten CheckSynchronize in OnIdle auzurufen.

Wenn man das macht, dann hat es aufeinmal ne Menge einfluss auf Threads die ihre Ausgabe mit dem Hauptthread synchronisieren.
Edit:
Hab gerade bemerkt das CheckSynchronize nie bei mir aufgerufen wird und Synchronize trotzdem ordnungsgemäß funktioniert...könnte das an FMX liegen oder an System.Classes.WakeMainThread ?

himitsu 7. Aug 2020 16:33

AW: TApplication.OnIdle Event
 
Wobei CheckSynchronize im ProcessMessage schon drin ist.
Und wenn dort nichts gemacht wurde und du es dann nochmal aufrufst, dann sollte ja nichts In der SynchronizeQueue drin sein (sonst würde OnIdle nicht aufgerufen), damit dürfte CheckSynchronize nicht machen und es würde keinerlei Unterschied geben. :roll:

QuickAndDirty 7. Aug 2020 16:39

AW: TApplication.OnIdle Event
 
Zitat:

Zitat von himitsu (Beitrag 1471368)
Wobei CheckSynchronize im ProcessMessage schon drin ist.
Und wenn dort nichts gemacht wurde und du es dann nochmal aufrufst, dann sollte ja nichts In der SynchronizeQueue drin sein (sonst würde OnIdle nicht aufgerufen), damit dürfte CheckSynchronize nicht machen und es würde keinerlei Unterschied geben. :roll:

hm,
Ich versuche ja Processmessages zu vermeiden...nur beim Anyindicator und bei Laufbalken kommt es zum einsatz.
OMG....
Das erklärt warum damals Processmessages und Threads in Kombination so Wirre effekte hervorgerufen haben. Und ich Processmessages(und Timer) deswegen ziemlich abgeschafft habe.
Gibt es eine ProcessMessages variante die nicht CheckSynchronize aufruft?

himitsu 7. Aug 2020 17:22

AW: TApplication.OnIdle Event
 
ProcessMessages ruft in einer Schleife ProcessMessage auf (bis es nichts mehr gibt)
aber auch Application.Run führt ProcessMessage aus, was dann übrigens normalerweise deine Events (Button-Click, Tastatur, Maus, Timer, Paint, Synchronize, ...) ausführt.

Also nach deinem Event wird sowieso ProcessMessage ausgeführt
und wenn dein Event zu lange braucht, dann "kannst" Du zwischendurch auch ProcessMessage (Eins / das Erste) oder ProcessMessages (Alles) ausführen und die angefallenen Arbeiten vorziehen.

Zitat:

Gibt es eine ProcessMessages variante die nicht CheckSynchronize aufruft?
Nicht, dass ich wüsste.


Bei uns in der Firma hatte ich mal ein ProcessDrawMessage eingebaut (aber so ganz richtig kann es nie funktionieren),
da hab ich versucht mit PeekMessage/GetMessage nur Messages rauszuholen und zu verarbeiten, die keine Tastatur, Maus oder Timer sind und auch das Synchronize ist nicht drin,
um nur Zeichen- und Speicheroperationen ausführen zu lassen, aber eben keine anderen Aktionen vorzeitig reinrutschen zu lassen.

Uwe Raabe 7. Aug 2020 22:10

AW: TApplication.OnIdle Event
 
Ich weiß jetzt nicht, ob es an der Delphi-Version liegt, aber in 10.4 wird CheckSynchronize nur in Idle aufgerufen - nicht in ProcessMessages.
Idle wird allerdings in HandleMessage aufgerufen falls keine Message vorliegt. Das ist die Methode, die in einer Dauerschleife in Application.Run aufgerufen wird. Das bedeutet aber nicht, dass ständig Idle aufgerufen wird. Bei Done = True wird am Ende von Idle ein WaitMessage aufgerufen.
Zitat:

The WaitMessage function suspends the thread and does not return until a new message is placed in the thread's message queue.
Zu häufige Idle-Events (z.B. in manchen MDI-Apps) kann man übrigens mit Application.ActionUpdateDelay bändigen.

Es gibt noch ein paar andere Events, die CheckSynchronize mittels WM_NULL auslösen, aber die sind hier eigentlich nicht von Belang.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:37 Uhr.
Seite 1 von 2  1 2   

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