[英]Rethrowing inner exception of an AggregateException
Let's say I have an Interface: 假设我有一个接口:
interface A {
string Do();
}
and then I implement this interface in a class. 然后我在一个类中实现此接口。 The implementation requires some async operations.
该实现需要一些异步操作。 Something like the following:
类似于以下内容:
class B : A {
public string Do() {
return Task1().Result;
}
private async Task<string> Task1() {
var str = await Task2();
return str + "task1";
}
private async Task<string> Task2() {
using (WebClient client = new WebClient())
{
return System.Text.Encoding.UTF8.GetString(await client.DownloadDataTaskAsync(new Uri("http://test.com")));
}
}
}
What is the proper way to return, to the external calling code, the first exception that occurs in the async operations chain? 将异步操作链中发生的第一个异常返回给外部调用代码的正确方法是什么? Is the following a good approach?
以下是好的方法吗?
public string Do() {
try {
return Task1().Result;
} catch (AggregateException ex) {
Exception inner = ex;
while(inner.InnerException != null) {
inner = inner.InnerException;
}
throw inner;
}
}
From your code, through the while
, I think you want to throw the first exception in AggregateException
To do that, you can use Flatten 通过代码,通过
while
,我认为您想在AggregateException
引发第一个异常。为此,您可以使用Flatten
Flattens an AggregateException instances into a single, new instance.
将AggregateException实例展平为单个新实例。
It helps to put the exceptions in "the same hierarchy", you can then simply call FirstOrDefault
to get the first exception. 这有助于将异常置于“相同的层次结构”中,然后可以简单地调用
FirstOrDefault
来获取第一个异常。
Supposed this code: 假设此代码:
Task.Factory.StartNew(
async () =>
{
await Task.Factory.StartNew(
() => { throw new Exception("inner"); },
TaskCreationOptions.AttachedToParent);
throw new Exception("outer");
}).Wait();
}
The stucture of exceptions likes 异常结构喜欢
AggregateException
Exception: outer
AggregateException
Exception: inner
With Flatten
, I can get inner
有了
Flatten
,我可以获得inner
catch(AggregateException ex)
{
Console.WriteLine(ex.Flatten().InnerExceptions.FirstOrDefault().Message);
}
but without Flatten
, I get AggregateException
, which isn't correct 但是没有
Flatten
,我得到AggregateException
,这是不正确的
catch(AggregateException ex)
{
Console.WriteLine(ex.Flatten().InnerExceptions.FirstOrDefault().Message);
}
With your case, this line can help you get the first exception 对于您的情况,此行可以帮助您获得第一个例外
ex.Flatten().InnerExceptions.FirstOrDefault().Message
You have also the method Handle , which help you handle the exception inside AggregateException
您还有方法Handle ,它可以帮助您处理
AggregateException
内部的异常
catch (AggregateException ex)
{
ex.Handle(x =>
{
if (x is UnauthorizedAccessException)
{
//the exception you interested
throw x;
}
// Other exceptions will not be handled here.
//some action i.e log
return false;
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.