2012-12-03 2 views
6

어떻게이 방법에서 예외를 잡을까요?비동기 HttpWebRequest 호출에서 예외 잡기

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

    } 

등 오류가 난 404를 얻고 특정 장소, 403이다 : 나는 당신의 오류가 아마 당신의 대리인이 request.EndGetResponse(asyncResult)를 호출에서 어떤 일이 일어나고 그들에게

답변

11

을 처리하는 방법을 알아낼 질수

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

. 다음을 사용하여 작업을 만들 수 있습니다 그러나

: 작업에 예외를 전달해야

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

.

당신은 당신의 ContinueWith 위임에 오류를 확인할 수 있습니다

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

을 또는 당신은 당신이 당신의 MakeAsyncRequest를 만들 비동기/await를 사용할 수 있습니다 C# 5를 사용하는 경우. 이것은 AggregateException에서 예외를 랩을 해제 :

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

그것은 지금 반환 task.ContinueWith에서 예외를 제공합니다 (t => FinishWebRequest (t.Result)); "하나 이상의 오류가 발생했습니다." – Jacqueline

+0

@ 재클린 - 요청이 예외를 던지고 있습니다 - 오류가 무엇입니까? – Lee

+0

"하나 이상의 오류가 발생했습니다."라고 표시됩니다. – Jacqueline

0

그래서 작업에 오류 상태로 상태를 변경하고 여러 가지 방법으로이 오류를 확인할 수 있습니다

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

당신이 준비해야 어떤 경우 모든 작업이 실패 할 수 있습니다, 그래서 당신은뿐만 아니라 작업을 결과 처리하기 위해 동일한 기술을 사용하도록 :

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