![]() |
Application - Hang (Anwendung Reagiert nicht) bei längeren Operationen: Lösung?
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
ich habe jetzt mal noch ein wenig mit dem Problem experimentiert, das Windows immer meldet "Anwendung reagiert nicht mehr" sobald eine Operation länger als ein 3 Sekunden braucht (zumindest, wenn der Anwender noch einmal rumklickt). Die Variante sämtliche längeren Operationen in Threads auszulagern finde ich ja von vorn herein absolut blödsinnig. Die Erkenntnis: ich habe eine sehr sehr einfach Lösung gefunden. In Kurz:
Delphi-Quellcode:
dies zeichnet alles neu und hält die Anwendung am Leben, Nutzereingaben werden nicht bearbeitet. Ist im MSDN auch genauso beschrieben.
PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE);//Refresh Application
![]()
Delphi-Quellcode:
entfernt sämtliche Nutzereingabe, wodurch verhindert wird, das am Ende einer Schleife alles bearbeitet wird, do der Nutzer während der Wartezeit dumm rumgeklickt hat.
while PeekMessage(Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) do;
while PeekMessage(Msg, 0, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE) do; Damit ist eigentlich klar, das anstatt einem Application.ProcessMessages zum Refresh der Anwendung die obigen Befehle aufgerufen werden sollten. Ich habe somit eine Funktion geschrieben:
Delphi-Quellcode:
Im Anhang eine ganz einfache Testanwendung. Was haltet Ihr davon?
procedure TForm11.ApplicationRefresh(RemoveUserInput: Boolean);
var Msg : TMsg; begin PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE);//Refresh Application if RemoveUserInput then begin while PeekMessage(Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) do ;//User Mouse Removed while PeekMessage(Msg, 0, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE) do ;//User Key Removed end; end; |
AW: Application - Hang (Anwendung Reagiert nicht) bei längeren Operationen: Lösung?
Jo, interessant!
Nenns KeepAlive / Unfreeze das kann man nun als eine andere Option zu Delay sehen ^^ Soetwas müsste man direkt in die oberste Basisklasse für sichtbare Controls packen damit man dann ganz einfach Self/Form1.KeepAlive/Unfreeze aufrufen kann. |
AW: Application - Hang (Anwendung Reagiert nicht) bei längeren Operationen: Lösung?
Vor allem macht dies auch automatisch die notwendigen Zeichenoperationen (auch so im MSDN beschrieben).
Letzlich wird ja nicht einmal etwas verändert: die Nachrichtenwarteschlange der Anwendung bleibt, wie sie ist. Die Anwendung arbeitet anschliessend ganz normal weiter. Sämtliche Timer etc verhalten sich ganz normal. Einzig Windows wird dadurch benachrichtigt, das die Anwendung kontrolliert die Nachrichtenwarteschlange abarbeitet. |
AW: Application - Hang (Anwendung Reagiert nicht) bei längeren Operationen: Lösung?
Ich habs mal ein bisschen umgeschrieben (Class Helper)
Delphi-Quellcode:
type
// Control-F1: "Controls.TControl is the base class for all components that are visible at runtime." // .. und weil nur mit sichtbaren controls interagiert werden kann (onclick, ...), wirds frühestens bei TControl benötigt TControlKeepAliveHlp = class helper for TControl public procedure KeepAlive(const DropUserInput: Boolean = True); end; procedure TControlKeepAliveHlp.KeepAlive(const DropUserInput: Boolean); // "DSCHUSCH" var DummyMsg: TMsg; begin PeekMessage(DummyMsg, 0, 0, 0, PM_NOREMOVE); if DropUserInput then begin while PeekMessage(DummyMsg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) do; while PeekMessage(DummyMsg, 0, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE) do; end; end; |
AW: Application - Hang (Anwendung Reagiert nicht) bei längeren Operationen: Lösung?
@Aphton ich sehe gerade nicht warum das ganze an einem Control hängen soll, es wird doch die Messagepipe mit 0, also für alle Handles abgefragt und (teil)geleert.
|
AW: Application - Hang (Anwendung Reagiert nicht) bei längeren Operationen: Lösung?
Hmm..
Schlag was was besseres vor. Das ist das, worauf ich auf die schnelle gekommen bin. Ich dachte mir, dass man, wenn man schon auf so Sachen wie delay() und eben dann keepAlive() ausweicht, schlechtes Design anwendet (GUI/Logik Trennung) und wenn man schon Dirty-Dinge macht - also in der GUI (sichtbare Controls -> Basisklasse Control) Berechnungen durchführt, dann kann man ja direkt hier mit keepAlive() ansetzen. :stupid: |
AW: Application - Hang (Anwendung Reagiert nicht) bei längeren Operationen: Lösung?
Zitat:
Zitat:
Delphi-Quellcode:
:mrgreen:
procedure keepAlive(const DropUserInput: Boolean); // "DSCHUSCH"
var DummyMsg: TMsg; begin PeekMessage(DummyMsg, 0, 0, 0, PM_NOREMOVE); if DropUserInput then begin while PeekMessage(DummyMsg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) do; while PeekMessage(DummyMsg, 0, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE) do; end; end; @DSCHUSCH: Coole Lösung :thumb: |
AW: Application - Hang (Anwendung Reagiert nicht) bei längeren Operationen: Lösung?
Blumen auch an Himitsu, er hat die Grundidee erarbeitet. 8-)
Ja - so habe ich das jetzt auch testhalber in Verwendung - callbacks, welche die Application am Leben halten, ohne das man sonstwas bauen muß. Die Anwendung ist geblockt aber reagiert für Windows (kein Hang), Nutzereingaben werden ignoriert, genauso wie es sein muß. Das alles ohne Disable/Enable und wtf ever für einen blödsinnigen, aufwendigen Nudelcode, der sowieso nur zu Nebeneffekten führt. (zB da durch Application.ProcessMessages ja auch Timer aufgerufen werden können). Funktionieren tut das aber auch nur aus dem Hauptthread heraus. Die Anwendung muß also nach wie vor vernünftig designed sein. Achtung - beim Testen im Debugger verhält sich das anders, als wenn die Anwendung ohne Debugger läuft - Delphi hält die Debug-Anwendung hier sicher selbst am Leben, damit Windows nicht meckert "Anwendung reagiert nicht". |
AW: Application - Hang (Anwendung Reagiert nicht) bei längeren Operationen: Lösung?
Kann dies mal jemand auf Windows Vista/XP/8 probieren? Die Testanwendung bietet ja die Option mit dem Radiobutton die Funktion an- und abzuschalten.
|
AW: Application - Hang (Anwendung Reagiert nicht) bei längeren Operationen: Lösung?
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:50 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 by Thomas Breitkreuz