Le code suivant illustre le problème de manière minimale. Dans un thread d'arrière-plan, je crée un tableau de handles valide et le passe à WaitForMultipleObjects
et cela attend avec succès sur les objets.WaitForMultipleObjects fonctionne, MsgWaitForMultipleObjects échoue - pourquoi?
Lors du passage du même tableau à MsgWaitForMultipleObjects
, cependant, l'appel de fonction échoue (WAIT_FAILED
) avec ERROR_INVALID_HANDLE
.
Qu'est-ce que je fais mal?
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows, SyncObjs, Classes;
type
TMyThread = class(TThread)
protected
procedure Execute; override;
end;
procedure TMyThread.Execute;
var
LEvent : TEvent;
LWaitHandles : TWOHandleArray;
LPWaitHandles : PWOHandleArray;
LWaitResult : Cardinal;
begin
LEvent := TEvent.Create;
LWaitHandles[0] := LEvent.Handle;
LPWaitHandles := @LWaitHandles;
while not Terminated do begin
{Works -> LWaitResult := WaitForMultipleObjects(1, LPWaitHandles, false, INFINITE);}
{Fails ->} LWaitResult := MsgWaitForMultipleObjects(1, LPWaitHandles, false, INFINITE, QS_ALLINPUT);
case LWaitResult of
WAIT_OBJECT_0: WriteLn('Event 1 Signaled');
{ etc... }
WAIT_FAILED : WriteLn(SysErrorMessage(GetLastError));
end;
end;
end;
var
lt : TMyThread;
begin
lt := TMyThread.Create(false);
ReadLn;
end.
Est-ce le problème que le fil ne dispose pas d'une file d'attente de messages? Il n'en obtient qu'un lorsque vous appelez certaines fonctions. Comme PeekMessage, GetMessage, etc. Je ne me souviens pas de la liste complète. –
@DavidHeffernan Non, je l'ai juste compris - c'est un problème RTL (cohérence de type erratique dans les wrappers WinAPI). Même si aucun message n'est publié sur le thread, 'MsgWaitForMultipleObjects' ne doit toujours pas renvoyer' WAIT_FAILED'. –
Oh, je m'en souviens. L'encapsuleur RTL est boiteux. De plus, il est inutile de déclarer un tableau avec 64 éléments comme ça. Vous ne déclarez jamais un TWOHandleArray. –