2012-12-03 5 views
6

Aşağıdaki yöntemde istisnayı nasıl yakalarım?Bir Görevde Eşzamansız HttpWebRequest Çağrılarından özel durumları yakalamak

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

    } 

vb hataları i 404 alıyorum belirli bir yer, 403,: Ben senin hata muhtemelen temsilci request.EndGetResponse(asyncResult) arayarak oluyor onlara

cevap

11

işlemek anlamaya olamaz

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

. Eğer kullanarak görev oluşturabilirsiniz Ancak

: görev için herhangi bir istisna yaymak gerektiğini

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

.

Sen ContinueWith delege hataları kontrol edebilirsiniz:

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

Alternatif o zaman MakeAsyncRequest oluşturmak için zaman uyumsuz/bekliyoruz kullanabilirsiniz C# 5 kullanıyorsanız. Bu senin için AggregateException gelen istisnaları paketini olacaktır:

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

artık dönüş task.ContinueWith de bir istisna verir (t => FinishWebRequest (t.Result)); "Bir hata daha ortaya çıktı" – Jacqueline

+0

@Jacqueline - İsteğiniz bir istisna atıyor o zaman - hatalar neler? – Lee

+0

Sadece "Bir veya daha fazla hata oluştu" yazıyor. – Jacqueline

0

Yani senin görevin Arızalı duruma faz değiştirir ve çeşitli yollarla bu hatayı kontrol edebilirsiniz:

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

Eğer hazırlanmalısınız Her durumda herhangi bir görev başarısız olabilir, bu nedenle de görevleri çıkan işlemek için aynı tekniği kullanması gerektiğini:

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