waitforreadpoolwaitcallbacks立即返回,无需等待

WaitForThreadpoolWaitCallbacks returns immediately without waiting

本文关键字:等待 返回 waitforreadpoolwaitcallbacks      更新时间:2023-10-16

我在这里做错了什么,waitforreadpoolwaitcallbacks立即返回而不等待?

HANDLE hEvent = CreateEvent(0, FALSE, FALSE, 0);
...
PTP_WAIT Pwa = CreateThreadpoolWait(WaitCallback, NULL, NULL);
SetThreadpoolWait(Pwa, hEvent, NULL);
// Here we should wait until hEvent gets signaled
WaitForThreadpoolWaitCallbacks(Pwa, FALSE);
// Here we should get after hEvent gets signaled

waitforreadpoolwaitcallbacks从不等待,执行在waitforreadpoolwaitcallbacks之后继续。然而,如果事件获得信号,回调仍然会以任何方式被调用。无论之前是否调用了waitforreadpoolwaitcallbacks,该事件都将获得信号。

SetThreadPoolWait Timeout设置为NULL,表示永远等待。

指向FILETIME结构体的指针,该结构体指定绝对或等待操作应超时的相对时间。如果这参数指向正值,则表示绝对时间从1601年1月1日(UTC)开始,以100纳秒为间隔。如果这参数指向负值,则表示时间量相对于当前时间等待。有关时间的更多信息

如果该参数指向0,则等待立即超时。如果这参数为NULL,则等待时间不会超时。

Edit:似乎SetThreadpoolWait的调用本身不会将线程池等待项(PTP_WAIT)设置为挂起状态。如果是这种情况,如果CancelPendingCallbacks参数设置为FALSE, WaitForThreadpoolWaitCallbacks将等待。也可能是"取消待处理"这个词具有误导性。Pending也可能意味着事件一直在等待,已经发出信号,但是没有空闲的工作线程来启动回调方法。

另一个不太可能的原因可能是WaitForThreadpoolWaitCallbacks有bug。

似乎存在竞争条件:

选自MSDN Magazine

问题在于,wait对象只会在关联的同步对象发出信号或超时过期时将回调排队。在其中一个事件发生之前,不会对回调进行排队,Wait函数也不需要等待任何东西。解决方案是首先使用空指针值调用SetThreadpoolWait,告诉等待对象停止等待,然后调用waitforreadpoolwaitcallbacks以避免任何竞争条件:

SetThreadpoolWait(w.get(), nullptr, nullptr);
WaitForThreadpoolWaitCallbacks(w.get(), TRUE);