[英]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.