WP7 Распространение исключения из обратного вызова BeginGetResponse - PullRequest
4 голосов
/ 12 декабря 2010

Я использую HttpWebRequest для вызова веб-службы.Если AsyncCallback из BeginGetResponse выдает ошибку, я хочу распространить ее до моего основного потока программы.У меня проблемы с этим, потому что ошибка не распространяется за пределы AsyncCallback.Я пытался поместить блоки try / catch на каждом шаге цепочки HttpWebRequest, но он никогда не распространяется за пределы метода 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 Ответ

2 голосов
/ 12 декабря 2010

Я думаю, вы не понимаете, как работает асинхронный код и как выполнение обратного вызова вписывается в код вызова.

В пределах GetRequestStreamCallback, после вызова request.BeginGetResponse метод будетпродолжайте выполнение, а в вашем примере просто завершите.

Неизвестно, когда (или даже если) будет выполняться ResponseCallback или что произойдет в потоке пользовательского интерфейса, когда это произойдет.Из-за этого ResponseCallback будет выполняться в другом потоке.

Возможно, чтобы в обратном вызове выполнялся код в потоке пользовательского интерфейса (который вам потребуется, чтобы взаимодействовать с пользовательским интерфейсом),используя Dispatcher.BeginInvoke.Однако вы не можете выполнить это в контексте другого метода.

Хотя я бы не рекомендовал этого, вы можете взглянуть на это обсуждение по поводу появления обратного вызовавыполнять синхронно.Это заблокирует ваш поток пользовательского интерфейса, хотя и НЕ рекомендуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...