class 许多不同方法的异常过滤器
Exception filter for the class many different methods
在我使用 webApi 的客户端应用程序中,我有很多方法可以像这样异步调用 webApi:
var task = Task.Run(async () => await this.SaveObject(User));
return task.Result.Content;
如果保存的对象有问题,异步函数会抛出异常。在这种情况下,我的异常将根据它的类型在客户端上处理。问题是当异步任务抛出异常时,task.Result.Content
埋在 System.AggregateException
.
中
现在我是这样处理的:
try
{
var task = Task.Run(async () => await this.saveObject(User)); return task.Result.Content;
}
catch(AggregateException ex)
{
throw ex.InnerException;
}
我有太多相同的方法。我想知道是否有办法避免在每个方法中使用 try/catch 块。也许有一个异常过滤器机制,有点像在 webApi 上使用的机制,可以在一个地方捕获 class 内的所有异常?也许我可以用一些属性来标记需要的方法?
首先,我建议您不要在 Task
上使用 .Result
。参见 https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html or https://montemagno.com/c-sharp-developers-stop-calling-dot-result/。
如果您遵循上述建议并在 try
块中 await
一个 Task
,它将抛出实际异常而不是 AggregateException
,因此您可能能够完全避免重新抛出代码。
否则,如果您真的想坚持使用您的 .Result
代码,您可以编写一个通用的包装方法来为您处理常见的错误:
try
{
var task = Task.Run(async () => await this.Object(User));
return task.Result.Content;
}
catch(AggregateException ex)
{
throw ex.InnerException;
}
类似于:
return RunAsync(() => this.Object(User));
private T RunAsync<T>(Func<Task<T>> func)
{
try
{
var task = Task.Run(func);
return task.Result;
}
catch(AggregateException ex)
{
throw ex.InnerException;
}
}
编辑:
我刚刚意识到还有另一种方法(参见 http://blog.stephencleary.com/2014/12/a-tour-of-task-part-6-results.html),它稍微 "hacky" 因为它感觉更隐蔽但是这个:
var task = Task.Run(async () => await this.Object(User));
return task.GetAwaiter().GetResult().Content;
.GetAwaiter().GetResult()
将同步等待 Task
(根据 .Result
)但不会将任何抛出的异常包装在 AggregateException
中 - 这似乎是您的欲望。
在我使用 webApi 的客户端应用程序中,我有很多方法可以像这样异步调用 webApi:
var task = Task.Run(async () => await this.SaveObject(User));
return task.Result.Content;
如果保存的对象有问题,异步函数会抛出异常。在这种情况下,我的异常将根据它的类型在客户端上处理。问题是当异步任务抛出异常时,task.Result.Content
埋在 System.AggregateException
.
现在我是这样处理的:
try
{
var task = Task.Run(async () => await this.saveObject(User)); return task.Result.Content;
}
catch(AggregateException ex)
{
throw ex.InnerException;
}
我有太多相同的方法。我想知道是否有办法避免在每个方法中使用 try/catch 块。也许有一个异常过滤器机制,有点像在 webApi 上使用的机制,可以在一个地方捕获 class 内的所有异常?也许我可以用一些属性来标记需要的方法?
首先,我建议您不要在 Task
上使用 .Result
。参见 https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html or https://montemagno.com/c-sharp-developers-stop-calling-dot-result/。
如果您遵循上述建议并在 try
块中 await
一个 Task
,它将抛出实际异常而不是 AggregateException
,因此您可能能够完全避免重新抛出代码。
否则,如果您真的想坚持使用您的 .Result
代码,您可以编写一个通用的包装方法来为您处理常见的错误:
try
{
var task = Task.Run(async () => await this.Object(User));
return task.Result.Content;
}
catch(AggregateException ex)
{
throw ex.InnerException;
}
类似于:
return RunAsync(() => this.Object(User));
private T RunAsync<T>(Func<Task<T>> func)
{
try
{
var task = Task.Run(func);
return task.Result;
}
catch(AggregateException ex)
{
throw ex.InnerException;
}
}
编辑: 我刚刚意识到还有另一种方法(参见 http://blog.stephencleary.com/2014/12/a-tour-of-task-part-6-results.html),它稍微 "hacky" 因为它感觉更隐蔽但是这个:
var task = Task.Run(async () => await this.Object(User));
return task.GetAwaiter().GetResult().Content;
.GetAwaiter().GetResult()
将同步等待 Task
(根据 .Result
)但不会将任何抛出的异常包装在 AggregateException
中 - 这似乎是您的欲望。