![]() |
Re: Warten auf ...? MsgWaitForMultipleObjects
Du musst den kompletten Messagequeue nach einem Signal leeren, ansonsten könnte es vorkommen das die eine Message die du mit Peekmessage entfernst eine neue Message postet. In diesem Moment muß MsgWaitForSingleObject() immer wieder sofort zurückkehren, da ja eine Message im Queue ist.
Delphi-Quellcode:
Obiger code funktioniert bei mir. Stimmt, mit dem Threadhandle als Event gibt er WAIT_FAILED zurück. Damit ist mein vorletztes Posting falsch. procedure Test; var Msg: TMsg; begin WriteLn('Start'); while True do case MsgWaitForMultipleObjects(0, PDWord(nil)^, False, 100, QS_ALLEVENTS) of WAIT_OBJECT_0: if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then // while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do case Msg.Message of WM_QUIT: WriteLn('Quit'); else begin WriteLn('Message'); TranslateMessage(Msg); DispatchMessage(Msg); end; end; WAIT_FAILED: WriteLn('Failed'); WAIT_TIMEOUT: WriteLn('Timeout'); end; WriteLn('End'); end; Bei mir gibt obiger Source in meiner Console aus: Start Message Message Timeout Timeout Message -> bewegte Mousecursor Timeout Timeout Timeout Message -> Idle message wm_Timer usw. usw. Wenn der Timeout zu groß ist dann kann dieser nicht mehr eintreten da in normalen Applications das OS weakup Messages versendet, zB. wm_SysTimer. Gruß Hagen |
Re: Warten auf ...? MsgWaitForMultipleObjects
@jbg
Zitat:
Ich gehe mal von der Logik aus. PeekMessage() schaut nur im Queue nach ob eine Message vorhanden ist und liefert diese zurück. Damit könnte das OS also ein Flag pro Thread verwalten (zB. Zähler) um anzuzeigen das Messages im Queue sind. PeekMessage() in einer Loop würde also die meiste Zeit dieses Flag pollen, sofort zurückkehren und dann wiederum sofort Pollen. Bei GetMessage() hängt das von der Implementation ab. Da ich die nicht kenne muß ich Annahmen treffen. Der günstigste Fall nimmt an das GetMessage() so wie oben arbeitet. Also Ereignissorientiert, schön. Der ungünstige Fall nimmt an das GetMessage() mehr erledigen muß als nur Messages zu holen. Das GetMessage() noch aus Win2.0 bekannt ist und demzufolge Kompatibilitätsrestriktionen unterworfen ist. Das GetMessage() als Highlevel Funktion auf LowerLevel API zurückgreift und einfach in einer Loop per PeekMessage() pollt. Es steht also 3 zu 1 das GetMessage() pollen KÖNNTE. Also nehme ich an das der schlechteste Fall der ist mit dem ich rechnen muß, also Polling. Nutze ich obigen Weg so stelle ich garantiert auf Ereignissorierntiert um egal ob underlaying GetMessage() pollt oder auf Events aufsetzt. Ich egalisiere den Fakt ob gepollt wird oder nicht. Gruß Hagen |
Re: Warten auf ...? MsgWaitForMultipleObjects
Danke Hagen.
Dein obiger Post war nicht wirklich falsch. Du hattest es ja nur vorgeschlagen :) Aber du meinst, wenn ich sie dispatche dann klappt es - das muss ich mal probieren. TranslateMessage() muesste ich ja weglassen koennen, weil ich ja eh keinen Dialog an der Queue zu haengen habe. Ich teste aber vorsichtshalber beides. Danke vorerst. Falls sich noch was ergibt, melde ich mich nochmal. Ich hatte auch schon an eine Message gedacht ... vonwegen PeekMessage wartet nicht, bis eine gesendete Message auch gepostet wurde und so ... aber ich ging davon aus, dass wenn ich sie nicht sende, wohl kaum "irgendjemand" anders das tut. |
Re: Warten auf ...? MsgWaitForMultipleObjects
Hi Asserbad,
wenn deine Funktion fertig ist würde ich sie gerne sehen. Normalerweise sendet das OS periodisch Messages. Viele Windows Klassen nutzen einen SysTimer() der dann alle 500ms eine wm_SysTimer Message auslösst. Setze ich Timeout auf 5000 dann kommt nie WAIT_TIMEOUT da in der Zwischenzeit wm_SysTimer o.ä. periodisch gepostet wurde. Gruß Hagen |
Re: Warten auf ...? MsgWaitForMultipleObjects
Wie gewuenscht, mein Code:
Delphi-Quellcode:
Es war tatsaechlich die Sache mit dem Entfernen aus der Queue. Uebrigens, ich bekomme bei 5sec einen Timeout!
function MAC_Thread(pml: PMachineList): DWORD; stdcall;
var msg: TMsg; begin while True do case MsgWaitForMultipleObjects(0, PDWORD(nil)^, False, 5000, QS_ALLEVENTS) of WAIT_OBJECT_0: if PeekMessage(msg, 0, 0, 0, PM_REMOVE) then case msg.message of SIGNAL_STOP: begin {$IFDEF DEBUGGING} Writeln('MAC: Received STOP.'); {$ENDIF DEBUGGING} Exit; end; else DispatchMessage(msg); end; WAIT_TIMEOUT: begin {$IFDEF DEBUGGING} Writeln('MAC: Timeout ... scanning for machines'); {$ENDIF DEBUGGING} PostThreadMessage(pml^.Dispatcher, SIGNAL_MACLISTUPD, 0, 0); end; end; result := 0; end; Hier noch ein Workerthread:
Delphi-Quellcode:
function WorkerThread(x: Pointer): DWORD; stdcall;
var msg: TMsg; begin while True do begin if PeekMessage(msg, 0, 0, 0, PM_REMOVE) then case msg.message of SIGNAL_STOP: begin {$IFDEF DEBUGGING} Writeln('WRK: Received STOP.'); {$ENDIF DEBUGGING} Exit; end; SIGNAL_WRKSCANMAC: begin {$IFDEF DEBUGGING} Writeln('WRK: Now scanning machine with index ', msg.wParam); {$ENDIF DEBUGGING} DispatchMessage(msg); end; else DispatchMessage(msg); end; WaitMessage; // lay down to sleep ... until we receive a message end; result := 0; end; |
Re: Warten auf ...? MsgWaitForMultipleObjects
Zitat:
Eine Frage: Du nutzt den Weg über PostMessages() an Threads um eine zügige Abarbeitung zu gewährleisten ?? Ich frage weil du damit Kernel und User Objecte mixt, obwohl es doch besser wäre bei Threads mit reinen Kernel zu arbeiten, sprich Events, Semaphore usw. Gruß Hagen |
Re: Warten auf ...? MsgWaitForMultipleObjects
Zitat:
GetMessage ruft die gleiche interne Funktion auf, die auch WaitMessage aufruft. Und zu WaitMessage sagt das PSDK Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
|
Re: Warten auf ...? MsgWaitForMultipleObjects
@jbg, ja haste, danke für die Infos.
Was ich eigentlich zeigen wollte ist der Punkt wie ich programmiere wenn ich nur Vermutungen anstellen kann (einfach keine Zeit oder Lust alles debuggen zu müssen :-) Das Resultat dieser Überlegungen führt dazu das es, egal in welchem Context, nicht mehr pollt, alles bestens also und auch gut. Gruß Hagen |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:24 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