2012-12-03 28 views
6

Làm cách nào để tôi loại trừ ngoại lệ trong phương thức này?Bắt ngoại lệ từ các cuộc gọi HttpWebRequest không đồng bộ trong một nhiệm vụ

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

    } 

Vị trí cụ thể tôi đang nhận được 404, 403, vv lỗi là:

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

tôi không thể tìm ra cách để xử lý chúng

Trả lời

11

lỗi của bạn có lẽ xảy ra trong đại biểu của bạn gọi request.EndGetResponse(asyncResult) .

Tuy nhiên bạn có thể tạo ra các nhiệm vụ sử dụng:

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

mà phải tuyên truyền bất kỳ ngoại lệ đối với công việc.

Bạn có thể kiểm tra lỗi trong ContinueWith đại biểu của bạn:

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

Hoặc nếu bạn đang sử dụng C# 5 sau đó bạn có thể sử dụng async/chờ đợi để tạo MakeAsyncRequest của bạn. Điều này sẽ unwrap ngoại trừ từ AggregateException cho bạn:

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

Nó bây giờ đưa ra một ngoại lệ ở lại task.ContinueWith (t => FinishWebRequest (t.Result)); "Đã xảy ra thêm một số lỗi" – Jacqueline

+0

@Jacqueline - Yêu cầu của bạn là ném ngoại lệ sau đó - các lỗi là gì? – Lee

+0

Nó chỉ nói "Một hoặc nhiều lỗi đã xảy ra". – Jacqueline

0

Vì vậy, nhiệm vụ của bạn thay đổi trạng thái của nó đến tình trạng đứt gãy và bạn có thể kiểm tra lỗi này bằng nhiều cách:

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

Trong bất kỳ trường hợp bạn nên chuẩn bị rằng bất kỳ nhiệm vụ có thể thất bại, vì vậy bạn nên sử dụng kỹ thuật tương tự để xử lý kết quả công việc cũng như:

// 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); 
} 
Các vấn đề liên quan