[英]How to throw/catch the inner exception from a task?
假設我有一個簡單的方法:
private void MyMethod()
{
try {
myService.Do();
} catch (MyException ex) {}
}
我有一個使用HttpClient
的服務,我這樣做:
public void Do()
{
var response = client.GetAsync(url).Result; //Alas it's not async till now
}
現在我正在實現一個DelegatingHandler
並覆蓋SendAsync
:
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return await base.SendAsync(request, cancellationToken)
.ContinueWith<HttpResponseMessage>(task =>
{
HttpResponseMessage response = task.Result;
if (response.StatusCode == HttpStatusCode.NotFound)
{
throw new MyException();
}
return response;
}).ConfigureAwait(false);
}
在此處拋出MyException
之前,一切都按預期工作。 異常冒泡到調用者,但是,異常是AggregrateException
。
有沒有辦法拋出實際的異常本身,這樣就不需要對應用程序范圍內的代碼進行重大更改?
當在任務中引發異常時,然后使用Result
屬性,您將得到AggregateException
,其中真正的異常在此AggregateException
object 的InnerException
屬性中(您的異常由AggregateException
包裝)。
要獲得真正的異常(未包裝的異常),您可以使用GetAwaiter().GetResult()
:
var result = taskThatThrowsException.GetAwaiter().GetResult();
您也可以使用Result
屬性,但是您應該為異常處理指定一些條件;
try
{
var result = taskThatThrowsException.Result;
}
catch (AggregateException ex) when (ex.InnerException is MyException myException)
{
// use myException - it is your true unwrapped exception
}
但是你不應該阻塞異步代碼- 你應該異步等待 - 使用await
你也會得到你真正的解包異常:
var result = await taskThatThrowsException;
AggregrateException
是許多異常的合並,因為async
方法可以在其執行時拋出許多異常 .net 使用此 class 來返回所有異常。
要訪問內部異常,它有一個名為InnerExceptions
的屬性,它是一個包含所有拋出異常的只讀集合。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.