Следующий код минимально демонстрирует проблему. В фоновом потоке я создаю допустимый массив дескрипторов и передаю его в WaitForMultipleObjects
, и это успешно ждет объектов.WaitForMultipleObjects works, MsgWaitForMultipleObjects не работает - почему?
При передаче одного и того же массива в MsgWaitForMultipleObjects
, однако, вызов функции завершается с ошибкой (WAIT_FAILED
) с ERROR_INVALID_HANDLE
.
Что я делаю неправильно?
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.
Есть проблема, что поток не имеет очереди сообщений? Он получает только один, когда вы вызываете определенные функции. Как PeekMessage, GetMessage и т. Д. Не помню полный список. –
@DavidHeffernan Нет, я только что понял это - проблема RTL (непротиворечивость консистенции в оболочках WinAPI). Даже если сообщений нет в потоке, 'MsgWaitForMultipleObjects' еще не должен возвращать' WAIT_FAILED'. –
О, я это помню. Оболочка RTL является хромой. Кроме того, вам не нужно указывать массив с такими 64 элементами. Вы никогда не объявляете TWOHandleArray. –