2012-06-28 1 views
11

Привет я использую HttpClient похож на это:HttpClient - дело с совокупным исключениями

public static Task<string> AsyncStringRequest(string url, string contentType) 
{ 
    try 
    { 
     var client = new HttpClient(); 
     client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(contentType)); 

     return client.GetStringAsync(url).ContinueWith(task => { 
      return task.Result; 
     }); 
    } 
    catch (AggregateException ex) 
    { 
     throw ex; 
    } 
    catch (WebException ex) 
    { 
     throw ex; 
    }  
    catch (Exception ex) 
    { 
     throw ex; 
    } 
} 

Но я имею трудности работы с исключениями. Я добавил дополнительные блоки catch только для того, чтобы попытаться выполнить шаг, но ни одна из точек останова не попадает ни в один из блоков catch. Я понимаю, что с помощью Task исключение может возникать в другом потоке, чем вызывающий, поэтому исключение обернуто в контейнер агрегата, но я не уверен, что лучший способ справиться с этими исключениями.

Например, я делаю запрос к веб-службе и задаю недопустимый параметр в запросе, и генерируется исключение. Я хочу, чтобы я мог уловить общие исключения и посмотреть на innerexceptions, чтобы понять, почему запрос не удался, и вернуть дружеское сообщение.

Итак, мой вопрос: какой лучший способ поймать эти совокупные исключения и справиться с ними?

ответ

18

Исключение выбрасывается task.Result:

var client = new HttpClient(); 
client.DefaultRequestHeaders.Accept.Add(...); 
return client.GetStringAsync(url).ContinueWith(task => 
{ 
    try 
    { 
     return task.Result; 
    } 
    catch (AggregateException ex) 
    { 
     throw ex; 
    } 
    catch (WebException ex) 
    { 
     throw ex; 
    }  
    catch (Exception ex) 
    { 
     throw ex; 
    } 
}); 

Лучше: проверить, если задача faulted перед обращением task.Result:

var client = new HttpClient(); 
client.DefaultRequestHeaders.Accept.Add(...); 
return client.GetStringAsync(url).ContinueWith(task => 
{ 
    if (task.IsFaulted) 
    { 
     var ex = task.Exception; 
    } 
    else if (task.IsCancelled) 
    { 
    } 
    else 
    { 
     return task.Result; 
    } 
}); 

Если вы на самом деле не делать что-то в ContinueWith, вы можете просто опустите его:

var client = new HttpClient(); 
client.DefaultRequestHeaders.Accept.Add(...); 
return client.GetStringAsync(url); 
+0

Отлично, я попробую его в следующий час! – gdp

+9

Я знаю, что это старый вопрос, но есть ли способ получить код статуса http из метода aggregateexception, как вы можете, когда поймаете webexception? – gdp

+0

@gdp: Да, вы можете вызвать .Flatten в AggregateException и затем получить доступ к свойству InnerExceptions и вытащить содержащееся в нем содержимое WebException. –