2015-03-03 100 views
2

我在同步模式下使用WinHTTP,沒有通過WINHTTP_FLAG_ASYNC標誌,我認爲回調總是被同步調用。這確實是大部分時間發生的事情,但有時候是,當調用WinHttpCloseHandle時,不會立即調用WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING通知調用回調。相反,它是從另一個線程之後被調用的。異步回調呼叫同步WinHTTP請求

那預期的行爲?爲什麼它會在某些情況下變成異步,如果這些信息是同步的?我知道如何解決它(如果我沒有馬上得知它,等待WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING通知),但我不明白爲什麼這就是我所看到的行爲。

回答

2

WinHTTP在同步模式下不承諾同步的「相同線程」回調。相反,MSDN states the opposite

回調函數必須是線程安全和可重入,因爲它可以在另一個線程單獨請求被調用,並重新進入當前請求在同一線程上。因此必須編碼以便在處理時安全地處理再入。當dwInternetStatus參數等於WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING時,回調不需要能夠處理同一請求的重入,因爲此回調保證是最後一次,並且在處理此請求的其他消息時不會發生。

這意味着,您所看到的症狀是基本的行爲由設計,並沒有涉及到異步模式:一些回調調用可能從工作線程發送到你,然後擰賽車可能會在回調下旬達到你的代碼。您需要考慮這一點,或者忽略那些遲到的呼叫,或與它們同步,或者明確地重置回調以明確不接收遲到的通知。

關於WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING具體MSDN解釋了您可以完全依賴的內容(請參閱上面的報價)。