繁体   English   中英

集中异步任务的异常

[英]Centralizing exceptions from asynchronous tasks

我在MVC应用程序中实现了自定义HandleErrorAttribute ,并且在某种程度上集中并捕获应用程序中发生的所有异常一直非常HandleErrorAttribute

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

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

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

并意识到我的CustomHandleErrorAttribute不会拦截那些方法中发生的异常:在这种情况下,如果DomeSomethingAsync()方法内部发生了异常,则我的HandleErrorAttribute将无法捕获该HandleErrorAttribute Global.asax不会。

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

一个好的方法是不要使用Task.Factory.StartNew ,尤其是不要在异步方法上使用。

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

await DoSomethingAsync();

Task.Factory.StartNew对于将工作卸载到ThreadPool线程很有用,但是您已经在ThreadPool线程上,因此Task.Factory.StartNew

如果您要放弃该任务,则应该意识到并不能保证它将继续运行。 任务运行时可以回收应用程序池,因为没有任何等待。

如果要在asp.net中执行“即发即忘”操作 ,则应使用类似HangFire的方法(有关Fire和ASP.NET上的 “忘记”的更多信息)


在asp.net之外的世界中,您可以使用ContinueWithTaskContinuationOptions.OnlyOnFaulted来简单地添加一个处理程序作为延续,以确保它仅在有例外的情况下运行,例如使用扩展方法:

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

并像这样使用它:

DoSomethingAsync().HandleExceptions();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM