4

我正在使用HttpWebRequest来调用Web服务。如果来自BeginGetResponse的AsyncCallback引发错误,我想将它传播到我的主程序流程中。我在这样做时遇到了麻烦,因为错误不会传播到AsyncCallback之外。我试过在HttpWebRequest链的每一步放置try/catch块,但它永远不会传播超出“ResponseCallBack”方法。是否有可能回到主线程?WP7从BeginGetResponse回调中传播异常

private void StartRequest() 
{ 
    // Code to create request object is here 
    // ... 

    httpRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), httpRequest); 
} 

private void GetRequestStreamCallback(IAsyncResult result) 
{ 
    HttpWebRequest request = (HttpWebRequest)result.AsyncState; 

    // End the operation 
    var postStream = request.EndGetRequestStream(result); 
    string body = GenerateRequestBody(); 

    // Convert the string into a byte array 
    byte[] postBytes = Encoding.UTF8.GetBytes(body); 

    // Write to request stream 
    postStream.Write(postBytes, 0, postBytes.Length); 
    postStream.Close(); 

    // Start the asynchronous operation to get the resonse 
    try 
    { 
     request.BeginGetResponse(new AsyncCallback(ResponseCallback), request); 
    } 
    catch (Exception) 
    { 
     throw; 
    } 
} 

private void ResponseCallback(IAsyncResult result) 
{ 
    string contents = String.Empty; 
    HttpWebRequest request = (HttpWebRequest)result.AsyncState; 
    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result); 

    using (Stream stream = response.GetResponseStream()) 
    using (StreamReader reader = new StreamReader(stream)) 
    { 
     contents = reader.ReadToEnd(); 
    } 

    // Check the status 
    if (response.StatusCode == HttpStatusCode.OK) 
    { 
     //EXCEPTION NEVER MAKES IT PASSED HERE, EVEN IF I HAVE IT IN A TRY/CATCH BLOCK AND RE-THROW IT. 
     _object = ProcessResponseEntity(contents); 
    } 
} 

回答

2

我认为你得到困惑的方式异步代码exectution工作原理和回调执行适合在与调用代码。

GetRequestStreamCallback之内,在对request.BeginGetResponse的调用之后,该方法将继续执行,并在您的示例中结束。

不知道什么时候(或者甚至)ResponseCallback将会执行,或者当UI线程执行时会发生什么。因此,ResponseCallback将在不同的线程上执行。

通过使用Dispatcher.BeginInvoke,可以在UI线程(您需要与UI进行交互时需要做的事)上执行回调代码。但是,您不能在另一种方法的上下文中执行此操作。

尽管我不会推荐它,但您可能需要查看this discussion以使回调显示为同步执行。这会阻止你的UI线程,所以不推荐。