【问题标题】:How can I guarantee that IXMLHTTPRequest2 callbacks will be called on a different thread?如何保证将在不同的线程上调用 IXMLHTTPRequest2 回调?
【发布时间】:2012-12-18 16:58:10
【问题描述】:

我正在使用 IXMLHTTPRequest2/IXMLHTTPRequest2Callback 接口发送 HTTP 请求并处理响应。有时响应回调(OnHeadersAvailable() 等)在与发送请求的线程不同的线程上调用,有时回调在发送请求的同一线程上调用,如下面的调用堆栈所示:

my.dll!xxxXMLHTTPRequest2Callback::OnHeadersAvailable(IXMLHTTPRequest2 * pXHR, unsigned long dwStatus, const wchar_t * pwszStatus) Line 185 C++
msxml6.dll!URLMONRequest::_CallOnHeadersAvailable() Line 305    C++
msxml6.dll!URLMONRequest::_OnResponse(unsigned long dwResponseCode, const wchar_t * pwszResponseHeaders, const wchar_t * pwszRequestHeaders) Line 2946  C++
msxml6.dll!URLMONRequest::OnResponse(unsigned long dwResponseCode, const wchar_t * pwszResponseHeaders, const wchar_t * pwszRequestHeaders, wchar_t * * ppwszAdditionalRequestHeaders) Line 2993    C++
msxml6.dll!URLMONRequest::URLMONRequestSink::OnResponse(unsigned long dwResponseCode, const wchar_t * szResponseHeaders, const wchar_t * szRequestHeaders, wchar_t * * pszAdditionalRequestHeaders) Line 212    C++
urlmon.dll!CINetHttp::QueryStatusOnResponseDefault()    Unknown
urlmon.dll!CINetHttp::QueryStatusOnResponse()   Unknown
urlmon.dll!CINetHttp::INetAsyncSendRequest()    Unknown
urlmon.dll!CINetHttp::INetAsyncOpenRequest()    Unknown
urlmon.dll!CINet::INetAsyncConnect()    Unknown
urlmon.dll!CINet::INetAsyncOpen()   Unknown
urlmon.dll!CINet::StartCommon() Unknown
urlmon.dll!CINet::Start()   Unknown
msxml6.dll!URLMONRequest::send(tagVARIANT varBody) Line 838 C++
msxml6.dll!XMLHttp::send(tagVARIANT varBody) Line 549   C++
msxml6.dll!XMLHttp2::_Send(ISequentialStream * pBody, unsigned __int64 cbBody) Line 2440    C++
msxml6.dll!XMLHttp2::Send(ISequentialStream * pBody, unsigned __int64 cbBody) Line 2993 C++

我希望回调总是在不同的线程上调用,因为这被记录为异步接口。有没有一种方法可以保证回调总是在与发送请求的线程不同的线程上被调用?感谢您提供任何信息。

【问题讨论】:

    标签: windows-8 microsoft-metro windows-runtime winrt-async


    【解决方案1】:

    “异步”只是意味着它不会消耗线程池中的线程,直到有结果可供处理。

    除了编写自己的池管理器之外,您无法控制异步请求的结果如何分配给给定线程。

    您可以让接收异步回调队列结果的线程(例如,使用 BlockingCollection)并让您选择的线程将工作项从队列中拉出。这样,即使您无法控制哪个线程接收结果,您也可以控制哪个线程处理结果。

    【讨论】:

    • 非常感谢。对于那些感兴趣的人,我在这里找到了关于异步与线程的一个很好的解释asynchronous vs. threading
    【解决方案2】:

    如果您在应用程序主线程上,默认行为似乎是在当前线程上回调,如果您在后台工作线程上,则使用另一个线程。这是基于我在从主线程发送请求时开始在 Win8 商店应用程序中看到的一些错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多