集中异步任务的异常

时间:2015-07-14 23:02:15

标签: c# asp.net-mvc-4 asynchronous exception-handling task-parallel-library

我在我的MVC应用程序中实现了一个自定义HandleErrorAttribute,它一直在以某种方式集中并捕获应用程序中发生的所有异常。

public class CustomHandleErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        ....
    }
}

问题是:我已经开始实现一些异步任务,比如这个:

Task.Factory.StartNew(() => DoSomethingAsync());

并意识到我的CustomHandleErrorAttribute没有拦截这些方法中发生的异常:在这种情况下,如果在DomeSomethingAsync()方法中发生异常,那么我的HandleErrorAttribute赢了“抓住它;并且Global.asax也不会。

集中异步任务中发生的异常有什么好的实现?我不想在每个方法中实现一个简单的try / catch块:我想用某种捕获它们的处理程序来计算。

1 个答案:

答案 0 :(得分:1)

一种好方法是不使用Task.Factory.StartNew,尤其是不使用异步方法。

直接调用异步方法并等待返回的任务。该任务中的异常将通过与所有其他异常相同的机制重新抛出和处理:

await DoSomethingAsync();

Task.Factory.StartNew对于将工作卸载到ThreadPool主题非常有用,但您已经在ThreadPool主题上,因此不需要这样做。

如果你想放弃那项任务,你应该意识到它不会继续运行。在任务运行时可以回收应用程序池,因为没有任何东西等待它。

如果您想在asp.net中执行"解雇" ,您应该使用类似HangFire的内容(Fire and Forget on ASP.NET中的更多内容)

在asp.net之外的世界中,您可以使用ContinueWithTaskContinuationOptions.OnlyOnFaulted简单地添加一个处理程序作为延续,以确保它仅在存在异常时运行,例如使用扩展方法:< / p>

public static void HandleExceptions(this Task task)
{
    task.ContinueWith(
        faultedTask => HandleException(faultedTask.Exception),
        TaskContinuationOptions.OnlyOnFaulted);
}

并像这样使用它:

DoSomethingAsync().HandleExceptions();