2012-12-03 14 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を取得しています特定の場所は次のとおりです。

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

私はあなたのエラーは、おそらくrequest.EndGetResponse(asyncResult)を呼び出すデリゲートで起こっている

答えて

11

それらを処理する方法を見つけ出すカント。あなたが使用してタスクを作成することができますしかし

:タスクに例外を伝播する必要があります

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

また、あなたがC#5を使用している場合、あなたはあなたのMakeAsyncRequestを作成するために、非同期/のawaitを使用することができます。これはあなたのため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(トン=> FinishWebRequest(t.Result)で例外を与えます); "1つ以上のエラーが発生しました" – Jacqueline

+0

@Jacqueline - リクエストが例外をスローしています - エラーは何ですか? – Lee

+0

「1つ以上のエラーが発生しました」と表示されます。 – 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); 
} 
関連する問題