WP7从BeginGetResponse回调传播异常

时间:2010-12-12 03:37:22

标签: c# silverlight windows-phone-7 httpwebrequest asynccallback

我正在使用HttpWebRequest来调用Web服务。如果BeginGetResponse的AsyncCallback抛出错误,我想将它传播到我的主程序流程。我在执行此操作时遇到问题,因为错误不会传播到AsyncCallback之外。我已经尝试在HttpWebRequest链的每一步放置try / catch块,但它从未传播到“ResponseCallBack”方法之外。是否有可能将其恢复到主线程?

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);
    }
}

1 个答案:

答案 0 :(得分:2)

我认为你对异步代码exectution的工作方式以及回调执行如何适应调用代码感到困惑。

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

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

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

虽然我不推荐它,但您可能需要查看this discussion以使回调看起来同步执行。这将阻止您的UI线程,因此不建议这样做。