![]() |
WaitForSingleObjectEx() ohne Timeout: Thread aufwecken
Hallo!
Ich benutze folgenden Code in einem Thread:
Delphi-Quellcode:
Eigentlich bin ich sehr zufrieden damit, da es sehr ressourcensparend ist und ich eigentlich keine Timeouts brauche.
dwWait := WaitForSingleObjectEx(
FConnectEventHandle, // event object to wait for INFINITE, // we have plenty of time true); Allerdings gibt es ein paar Fälle, wo ich den Thread beenden muss (z.B. Programmende). Da der Thread geblockt ist, kann ich Terminated nicht regelmäßig prüfen. Multithreading the Delphi Way (das beste Schriftstück, für Threads IMHO :mrgreen:) sagt dazu: Zitat:
1) Wie killt man so ein WaitForSingeObjectEx? 2) Wird Terminate() überhaupt ausgeführt, wenn der Thread geblockt ist? Ich nehme schon sehr stark an, aber... Danke, Andreas |
Re: WaitForSingleObjectEx() ohne Timeout: Thread aufwecken
Ja klar, wird die Methode ausgeführt. sie läuft ja im MainThread. Und du löst in der überschriebenen Methode dann dein Ereignis aus.
|
Re: WaitForSingleObjectEx() ohne Timeout: Thread aufwecken
Verstehe. Also überschreibe ich einfach die Terminate()-Methode meines Threads.
Also kann ich einfach mein Ereignis mit SetEvent() auslösen? Was mich bei dieser Geschichte am brennendsten interessiert: Welchen Rückgabewert hat dann WaitForSingleObjectEx? 0 und WAIT_IO_COMPLETION sind nämlich OK, alles andere wird als Fehler gerechnet. Jetzt wäre es gut, wenn ich es als Fehler rechnen könnte... Danke, Andreas |
Re: WaitForSingleObjectEx() ohne Timeout: Thread aufwecken
Ich setze einfach Terminated auf TRUE und zupfe dann am Event: Der Thread wacht auf und merkt 'Shit, muss mich beenden' und hört auf.
|
Re: WaitForSingleObjectEx() ohne Timeout: Thread aufwecken
Soweit habe ich das verstanden, nur:
Wie "zupfe" ich am Event (normalerweise wird das in diesem Fall von Windows erledigt)? Ich tippe auf SetEvent(FConnectEventHandle). Und ihr meint, dass mir der Rückgabewert von WaitForSingleObjectEx egal sein kann, weil ich einfach Terminated prüfe? Würde zumindest für mich logisch klingen... Danke, Andreas |
Re: WaitForSingleObjectEx() ohne Timeout: Thread aufwecken
Ja genau, Du löst das Event aus. Es ist nicht 100% genau, weil theoretisch der Event in dem Augenblick ausgelöst wird, in dem Du den Thread terminieren willst. In deinem Fall (Thread zum Prozessende terminieren) ist das aber wurscht.
|
Re: WaitForSingleObjectEx() ohne Timeout: Thread aufwecken
Moin Andreas,
je nachdem, was der Thread tun soll, wenn das Event eintritt, könntest Du dann auch noch, zur Sicherheit, ein Flag setzen, anhand dessen der Thread erkennt, dass er abgebrochen wurde. Dadurch kannst Du verhindern, dass eventuell noch weitere Aktionen eines normalen Durchlaufes ausgeführt werden. |
Re: WaitForSingleObjectEx() ohne Timeout: Thread aufwecken
inetwa so baue ich meine Threads auf:
Delphi-Quellcode:
Falls ich mehrere Events benötige dann baue ich FEvents[] als privates Feld der TThread Klasse und greife per indizierten Properties auf dieses Array zu. Das ist im Grunde der häufigste Fall der zutrift da man am besten mit Threads und Eventorientierten Funktionen arbeiten sollte, zb. Kommunikation per COM/Bluetooth/WinSock usw.
type
TMyThread = class(TThread) private FEvents: array[0..1] of THandle; function GetEvent(Index: Integer): THandle; // Result := FEvent[Index]; protected procedure Execute; override; public constructor Create(..params); destructor Destroy; override; property EventTerminate: THandle index 0 read GetEvent; property EventWorking: THandle index 1 read GetEvent; end; procedure TMyThread.Execute; begin try while not Terminated do case WaitForMultipleObjects(@FEvents, 2, .....) of WAIT_OBJECT_0 +0: Break; WAIT_OBJECT_0 +1: // ... mache sonstwas; else raise Exception.Create('ungültiges Resultat in Wait'); end; except // ...alle Exceptions hier behandeln end; end; Gruß Hagen |
Re: WaitForSingleObjectEx() ohne Timeout: Thread aufwecken
Verstehe.
D.h. die simple Methode, die für mich eventuell ausreicht, ist: Ich löse das Event aus und setze die Terminated-Property? Die Königslösung (und die strebe ich an) ist für das Beenden ein eigenes Event zu registrieren und statt WaitForSingeObjectEx mit WaitForMultipleObjects zu arbeiten. Werde das gleich mal einbauen und mich bei weiteren Problemen melden... Vielen Dank, Andreas |
Re: WaitForSingleObjectEx() ohne Timeout: Thread aufwecken
Ja, für jeden Zustand ein eigenes Event, oder aber ein threadsicheres Flag/Set und bei Änderung dieses, ein Event auslösen. Ich bevorzuge das Erstere da man dadurch mehrere dieser Events asynchron auslösen kann bzw. wenn man Eventbasierte APIs benutzt auch strikt nach Funktion separieren kann ohne Seiteneffekte zu provozieren. Das WaitForMultipleObjects() lässte sich auch einfach ersetzen durch MsgWaitForMultipleObjects() um einen Messagequeue zum Thread zu berücksichtigen.
Gruß hagen |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:44 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