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

Async callback call for a sync WinHTTP request

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

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

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

The callback function must be threadsafe and reentrant because it can be called on another thread for a separate request, and reentered on the same thread for the current request. It must therefore be coded to handle reentrance safely while processing. When the dwInternetStatus parameter is equal to WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING, the callback does not need to be able to handle reentrance for the same request, because this callback is guaranteed to be the last, and does not occur when other messages for this request are handled.

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

关于 WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING 具体而言,MSDN 解释了您可以确切依赖的内容(请参阅上面的引用)。