我在同步模式下使用WinHTTP,没有传递WINHTTP_FLAG_ASYNC
标志,我认为回调总是被同步调用。这确实是大部分时间发生的事情,但有时,在调用WinHttpCloseHandle
时,不会立即通过WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
通知调用回调。相反,它后来从另一个线程调用。
预期的行为?如果看到同步,为什么它会在某些情况下变得异常?我知道如何修复它(等待WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
通知,如果我没有立即得到它),但我不明白为什么这就是我所看到的行为。
答案 0 :(得分:2)
WinHTTP不承诺同步"相同的线程"同步模式下的回调。相反,MSDN states the opposite:
回调函数必须是线程安全的和可重入的,因为它可以在另一个线程上调用单独的请求,并在当前请求的同一线程上重新进入。因此必须对其进行编码以便在处理时安全地处理重入。当dwInternetStatus参数等于
WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
时,回调不需要能够处理同一请求的重入,因为此回调保证是最后一个,并且当此请求的其他消息是处理。
这意味着您看到的症状基本上是设计上的行为,并且与异步模式无关:某些回调调用可能会从工作线程发送给您,然后线程竞争可能会在回调后期到达您的代码。您需要考虑这一点并忽略这些延迟调用,或者与它们同步,或者明确地尽早重置回调以不接收延迟通知。
关于WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
,MSDN特别解释了您可以完全依赖的内容(参见上面的引用)。