Waitforsingleobject for event不起作用

时间:2013-11-28 11:07:02

标签: delphi winapi synchronization

主线程:

(是的,我现在停止主线程,我现在真的需要它进行测试,这是测试单元。我将在最后阶段在另一个线程中完成所有这些工作。)

代码:

function TFreHolder.GetVersion: TFreHolderVersion;
Var
 Data   : TBArray;
 StrLen : Integer;
begin
 SetLength(Data, 0);

 FFrePro.SendCommand(PROTO_COMVERSION, Data);

 ResetEvent(FAsyncMutex);

 if (WaitForSingleObject(FAsyncMutex, PROTO_COMMANDTIMEOUT) = WAIT_TIMEOUT) Then
  Begin
   ShowMessage('Timeout');
   ResetEvent(FAsyncMutex);
   Exit;
  End;

Result.DType    := BytesToWord(FActivePackage.User.Parameters, 0);
Result.DVersion := BytesToWord(FActivePackage.User.Parameters, 2);
StrLen          := BytesToByte(FActivePackage.User.Parameters, 4);

if StrLen < 32
  then Result.DDesc    := BytesToString(FActivePackage.User.Parameters, 5)
  else Result.DDesc    := BytesToString(FActivePackage.User.Parameters, 4);

在COM端口观察线程中:

procedure TFreHolder.CommandSwitcher(Package: TFreProPackage);
...
Begin
     FActivePackage := Package;
     SetEvent(FAsyncMutex)
End;
...

我总是看到超时消息,但如果我评论Waitforsingleobject,我可以看到字节和包即将到来。

我在构造函数中以这种方式创建了Event:

FAsyncMutex  := CreateEvent(Nil, True, False, 'FRE_EVENT');

我的错误是什么?在获取结果之前,我需要等待CommandSwitcher函数的调用。

感谢。

2 个答案:

答案 0 :(得分:6)

代码

ResetEvent(FAsyncMutex);
if (WaitForSingleObject(FAsyncMutex,...

绝对是一个错误,因为它忽略了线程的异步性质。

答案 1 :(得分:4)

假设另一个线程正在接收响应,然后在收到响应时发出FAsyncMutex信号,那么您需要在调用ResetEvent()之前调用SendCommand(),而不是之后。如果线程恰好在发送方能够调用ResetEvent()之前收到响应,那么它会通过清除它正在等待的条件来强制WaitForSingleObject()超时。

此外,如果WaitForSingleObject()超时等待事件发出信号,请不要致电ResetEvent(),因为事件未被点击。

试试这个:

var
  Ret: DWORD;
...
ResetEvent(FAsyncMutex);
FFrePro.SendCommand(PROTO_COMVERSION, Data);

Ret := WaitForSingleObject(FAsyncMutex, PROTO_COMMANDTIMEOUT);
if Ret <> WAIT_OBJECT_0 then
begin
  if Ret = WAIT_TIMEOUT then
    ShowMessage('Timeout')
  else
    ShowMessage('Error');
  Exit;
end;