4

J'utilise HttpWebRequest pour appeler un service Web. Si l'AsyncCallback de BeginGetResponse génère une erreur, je veux la propager jusqu'à mon flux de programme principal. J'ai du mal à le faire car l'erreur n'est pas propagée au-delà de l'AsyncCallback. J'ai essayé de mettre des blocs try/catch à chaque étape de la chaîne HttpWebRequest, mais il ne se propage jamais au-delà de la méthode "ResponseCallBack". Est-il possible de revenir au fil principal?WP7 Propager l'exception du rappel 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); 
    } 
} 

Répondre

2

Je pense que vous obtenez confus au sujet de la façon dont le code asynchrone fonctionne exectution et comment l'exécution de rappel s'inscrit dans le code d'appel.

Au sein de GetRequestStreamCallback, après l'appel à request.BeginGetResponse la méthode continuera à s'exécuter et dans votre exemple se terminera juste.

On ne sait pas quand (ou même si) ResponseCallback va s'exécuter ou ce qui se passera sur le thread de l'interface utilisateur quand c'est le cas. Pour cette raison, ResponseCallback s'exécutera sur un thread différent.

Il est possible d'avoir du code dans le rappel exécuté sur le thread d'interface utilisateur (dont vous aurez besoin pour interagir avec l'interface utilisateur) en utilisant Dispatcher.BeginInvoke. Cependant, vous ne pouvez pas l'exécuter dans le contexte d'une autre méthode.

Bien que je ne le recommanderais pas, vous voudrez peut-être jeter un oeil à this discussion pour que le rappel semble exécuter de façon synchrone. Cela va bloquer votre thread d'interface utilisateur et n'est donc pas recommandé.