4

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

1 に答える 1

2

非同期コードの実行方法と、コールバックの実行が呼び出し元のコードにどのように適合するかについて混乱していると思います。

GetRequestStreamCallbackでは、メソッドへの呼び出しがrequest.BeginGetResponse実行され続け、あなたの例ではちょうど終了します。

いつ実行されるか (または実行されるかどうか) は不明であり、ResponseCallback実行時に UI スレッドで何が発生するかは不明です。このためResponseCallback、別のスレッドで実行されます。

Dispatcher.BeginInvoke. _ ただし、これを別のメソッドのコンテキスト内で実行することはできません。

お勧めしませんが、コールバックが同期的に実行されているように見えるようにする方法については、こちらのディスカッションを参照してください。ただし、これは UI スレッドをブロックするため、お勧めしません。

于 2010-12-12T20:15:54.760 に答える