2012-12-03 1 views
6

Come posso rilevare l'eccezione in questo metodo di seguito?Catching exceptions from Async HttpWebRequest Calls in a Task

private static Task<string> MakeAsyncRequest(string url) 
    { 
     if (!url.Contains("http")) 
      url = "http://" + url; 

     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
     request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"; 
     request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; 
     request.Method = "GET"; 
     request.KeepAlive = false; 
     request.ProtocolVersion = HttpVersion.Version10; 

     Task<WebResponse> task = Task.Factory.FromAsync(
     request.BeginGetResponse, 
     asyncResult => request.EndGetResponse(asyncResult), 
     (object)null); 

     return task.ContinueWith(t => FinishWebRequest(t.Result)); 

    } 

Il luogo specifico sto ottenendo 404, 403, ecc errori è:

Task<WebResponse> task = Task.Factory.FromAsync(
      request.BeginGetResponse, 
      asyncResult => request.EndGetResponse(asyncResult), 
      (object)null); 

Non riesco a capire come gestirli

risposta

11

Il tuo errore è probabilmente accadendo nella vostra delegato chiamando request.EndGetResponse(asyncResult) .

Tuttavia è possibile creare l'attività utilizzando:

Task<WebResponse> task = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null); 

che dovrebbe propagarsi deroghe al compito.

È possibile verificare la presenza di errori nel ContinueWith delegato:

return task.ContinueWith(t => 
{ 
    if (t.IsFaulted) 
    { 
     //handle error 
     Exception firstException = t.Exception.InnerExceptions.First(); 
    } 
    else 
    { 
     return FinishWebRequest(t.Result); 
    } 
}); 

In alternativa, se si sta utilizzando C# 5 è possibile utilizzare asincrona/vi aspettano per creare il tuo MakeAsyncRequest. Ciò scartare l'eccezione della AggregateException per voi:

private static async Task<string> MakeAsyncRequest(string url) 
{ 
    if (!url.Contains("http")) 
     url = "http://" + url; 

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
    request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"; 
    request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; 
    request.Method = "GET"; 
    request.KeepAlive = false; 
    request.ProtocolVersion = HttpVersion.Version10; 

    Task<WebResponse> task = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null); 
    WebResponse response = await task; 
    return FinishWebRequest(response); 
} 
+0

ora dà un'eccezione al ritorno task.ContinueWith (t => FinishWebRequest (t.Result)); "Si sono verificati uno o più errori" – Jacqueline

+0

@Jacqueline - La richiesta sta generando un'eccezione quindi - quali sono gli errori? – Lee

+0

Dice solo "Si sono verificati uno o più errori". – Jacqueline

0

Così il vostro compito cambia il suo stato di stato di errore e si può controllare questo errore in diversi modi:

// Inside method MakeAsyncRequest 
Task<WebResponse> task = Task.Factory.FromAsync(
    request.BeginGetResponse, 
    asyncResult => request.EndGetResponse(asyncResult), 
    (object)null); 

// this 'task' object may fail and you should check it 

return task.ContinueWith(
    t => 
    { 
     if (t.Exception != null) 
      FinishWebRequest(t.Result)) 

     // Not the best way to fault "continuation" task 
     // but you can wrap this into your special exception 
     // and add original exception as a inner exception 
     throw t.Exception.InnerException; 

     // throw CustomException("The request failed!", t.Exception.InnerException); 
    }; 

In ogni caso si dovrebbe preparare che tutta l'operazione può fallire, così si dovrebbe utilizzare la stessa tecnica per gestire risultante compiti così:

// outside method MakeAsyncRequest 
var task = MakeAsyncRequest(string url); 

task.ContinueWith(t => 
    // check tasks state or use TaskContinuationOption 
    // handing error condition and result 
); 

try 
{ 
    task.Wait(); // will throw 
    Console.WriteLine(task.Result); // will throw as well 
} 
catch(AggregateException ae) 
{ 
    // Note you should catch AggregateException instead of 
    // original excpetion 
    Console.WriteLine(ae.InnerException); 
}