同步WinHTTP请求的异步回调调用

时间:2015-03-03 10:44:47

标签: winapi asynchronous winhttp

我在同步模式下使用WinHTTP,没有传递WINHTTP_FLAG_ASYNC标志,我认为回调总是被同步调用。这确实是大部分时间发生的事情,但有时,在调用WinHttpCloseHandle时,不会立即通过WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING通知调用回调。相反,它后来从另一个线程调用。

预期的行为?如果看到同步,为什么它会在某些情况下变得异常?我知道如何修复它(等待WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING通知,如果我没有立即得到它),但我不明白为什么这就是我所看到的行为。

1 个答案:

答案 0 :(得分:2)

WinHTTP不承诺同步"相同的线程"同步模式下的回调。相反,MSDN states the opposite

  

回调函数必须是线程安全的和可重入的,因为它可以在另一个线程上调用单独的请求,并在当前请求的同一线程上重新进入。因此必须对其进行编码以便在处理时安全地处理重入。当dwInternetStatus参数等于WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING时,回调不需要能够处理同一请求的重入,因为此回调保证是最后一个,并且当此请求的其他消息是处理。

这意味着您看到的症状基本上是设计上的行为,并且与异步模式无关:某些回调调用可能会从工作线程发送给您,然后线程竞争可能会在回调后期到达您的代码。您需要考虑这一点并忽略这些延迟调用,或者与它们同步,或者明确地尽早重置回调以不接收延迟通知。

关于WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING,MSDN特别解释了您可以完全依赖的内容(参见上面的引用)。