WaitForMultipleObjects工作,MsgWaitForMultipleObjects失败 - 为什么?

时间:2017-01-23 17:35:04

标签: multithreading delphi winapi delphi-10-seattle

以下代码最低限度地演示了该问题。在后台线程中,我创建了一个有效的句柄数组并将其传递给WaitForMultipleObjects,这成功地等待了对象。

但是,将完全相同的数组传递给MsgWaitForMultipleObjects时,函数调用将失败(WAIT_FAILEDERROR_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.

1 个答案:

答案 0 :(得分:5)

虽然handle参数的WinAPI签名对于这两个调用是相同的:

 _In_ const HANDLE *pHandles,
然而,RTL以不同的方式包装这些功能。 WaitForMultipleObjects使用指针类型:

lpHandles: PWOHandleArray;

MsgWaitForMultipleObjects使用无类型var参数:

var pHandles;

因此,句柄数组必须直接传递给MsgWaitForMultipleObjects

即:

LWaitResult := MsgWaitForMultipleObjects(1, LWaitHandles, false, INFINITE, QS_ALLINPUT);