我在我的MVC应用程序中实现了一个自定义HandleErrorAttribute
,它一直在以某种方式集中并捕获应用程序中发生的所有异常。
public class CustomHandleErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
....
}
}
问题是:我已经开始实现一些异步任务,比如这个:
Task.Factory.StartNew(() => DoSomethingAsync());
并意识到我的CustomHandleErrorAttribute
没有拦截这些方法中发生的异常:在这种情况下,如果在DomeSomethingAsync()
方法中发生异常,那么我的HandleErrorAttribute
赢了“抓住它;并且Global.asax
也不会。
集中异步任务中发生的异常有什么好的实现?我不想在每个方法中实现一个简单的try / catch块:我想用某种捕获它们的处理程序来计算。
答案 0 :(得分:1)
一种好方法是不使用Task.Factory.StartNew
,尤其是不使用异步方法。
直接调用异步方法并等待返回的任务。该任务中的异常将通过与所有其他异常相同的机制重新抛出和处理:
await DoSomethingAsync();
Task.Factory.StartNew
对于将工作卸载到ThreadPool
主题非常有用,但您已经在ThreadPool
主题上,因此不需要这样做。
如果你想放弃那项任务,你应该意识到它不会继续运行。在任务运行时可以回收应用程序池,因为没有任何东西等待它。
如果您想在asp.net中执行"解雇" ,您应该使用类似HangFire的内容(Fire and Forget on ASP.NET中的更多内容)
在asp.net之外的世界中,您可以使用ContinueWith
和TaskContinuationOptions.OnlyOnFaulted
简单地添加一个处理程序作为延续,以确保它仅在存在异常时运行,例如使用扩展方法:< / p>
public static void HandleExceptions(this Task task)
{
task.ContinueWith(
faultedTask => HandleException(faultedTask.Exception),
TaskContinuationOptions.OnlyOnFaulted);
}
并像这样使用它:
DoSomethingAsync().HandleExceptions();