WaitForSingleObject超时太快

4

我有这段代码在一个次要线程中:

DWORD result = WaitForSingleObject(myhandle,10000);
if(result == WAIT_OBJECT_0){
    AfxMessageBox(_T(...));
}
else if(result  == WAIT_TIMEOUT){

    AfxMessageBox(_T("Timeout"));
}

有时候,不是总是,当调用WaitForSingleObject时,超时函数会几乎立即被调用(甚至没有1秒的延迟)。
我做错了什么吗?有更稳定的替代方案吗?
编辑:
myhandle在类构造函数中被创建为:
myhandle = CreateEvent(NULL,FALSE,FALSE,_T("myhandle"));

它将被另一个函数调用:

SetEvent(myhandle);

问题在于当我执行SetEvent时它能工作,但有时候即使应该等待10秒,当调用WaitForSingleObject时它会立即超时。


你在等什么?myhandle是从哪里来的? - RedX
你在等待之前和之后检查了 GetLastError() 吗? - Mooing Duck
3个回答

1

WaitForSingleObject 不会等待整个10秒钟。它将等待以下三种情况中的第一种:

  1. 超时值已经过
  2. 事件被触发
  3. 句柄变为无效(在另一个线程中关闭)

如果在调用 WaitForSingleObject 时设置了事件,则条件#2从一开始就成立,WaitForSingleObject 立即返回。

如果您想要始终等待10秒钟,您应该使用以下代码:

//Always wait 10 seconds
Sleep(10000); 

//Test the event without waiting
if(WaitForSingleObject(myhandle, 0) == WAIT_OBJECT_0) {
    AfxMessageBox(_T("Event was set in the last 10 secondes"));
} else {
    AfxMessageBox(_T("Timeout"));
}

1

你真的需要/想要一个命名事件吗?通常这只在进程间并发控制时才需要。

如果您有多个该类的实例,它们都将使用相同的事件 - 请参阅CreateEvent文档关于调用已经存在的命名对象。也许你只需要在这里删除名称。这样可以使每个类实例拥有自己的Event对象,并且行为应该更可预测。


事件创建所在的类是单例模式。它从主视图中设置:Class::instance()->SetEvent(),其中代码片段为SetEvent(myhandle);我会尝试您建议的方法,即CreateEvent(NULL,FALSE,FALSE,NULL) - Smash
是的,但只有在多次调用该代码时才会产生影响。您是否运行多个程序实例? - Steve Townsend

0
花了一些时间,但问题实际上是程序有时会多次调用WaitForSingleObject。因此,超时的是先前的调用。
解决方案是使用WaitForMultipleObjects,并在已知第一个事件不会被设置的情况下设置取消事件,以便在重新调用计时器之前取消计时器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接