【发布时间】:2017-01-23 17:35:04
【问题描述】:
以下代码最低限度地演示了该问题。在后台线程中,我创建了一个有效的句柄数组并将其传递给WaitForMultipleObjects,这会成功等待对象。
但是,当将完全相同的数组传递给 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。
-
@DavidHeffernan 是的,我没有费心制作消息队列,因为它对于演示问题并不重要。是的,
TWOHandleArray很浪费——不过,它确实为 MCVE 节省了一行代码。 -
TWOHandleArray 很好。如果我注意 RTL 包装器,我就不会问this 问题。
标签: multithreading delphi winapi delphi-10-seattle