【问题标题】:Centralizing exceptions from asynchronous tasks集中异步任务的异常
【发布时间】:2015-10-03 19:30:04
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • await Task.Factory.StartNew(() => DoSomethingAsync());这样调用它会得到什么
  • @EZI 将异常冒泡到主线程。我不想要那个。我希望异步任务无论如何运行,主线程忽略异步任务的结果。
  • 这有帮助吗? dotnetcodr.com/2014/02/18/…
  • 即发即弃是不好的模式,但如果这是您正在寻找的几个现有副本。否则 i3arnon 的回答提供了很好的指导。请评论一下即发即弃是否是您正在寻找的。​​span>
  • @AlexeiLevenkov 我想要一种机制来实际捕获来自通用处理类中的即发即弃方法的所有异常。但你是对的:i3arnon 给出了一个很好的方法☺

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


【解决方案1】:

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

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

await DoSomethingAsync();

Task.Factory.StartNew 对于将工作卸载到 ThreadPool 线程很有用,但是您已经在 ThreadPool 线程上,所以不需要这样做。

如果您想放弃该任务,您应该意识到无法保证它会继续运行。应用程序池可以在任务运行时回收,因为没有任何等待。

如果你想在 asp.net 中进行“一劳永逸”,你应该使用 HangFire 之类的东西(更多内容请参见 Fire and Forget on ASP.NET


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

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

并像这样使用它:

DoSomethingAsync().HandleExceptions();

【讨论】:

  • 这会将异常冒泡到主线程。我不想那样。我希望异步任务无论如何运行,主线程忽略异步任务的结果。
  • @Silvestre 那你怎么知道任务完成了?
  • 作为主线程(在我的例子中,一个控制器的 Action 可以做很多事情——其中的异步任务)是不相关的:现在,从应用程序全局的角度来看:我希望能够拦截异步线程中任何可能的异常。但是你可能是对的,没有什么能保证异步任务的连续性......但现在,我将专注于异常捕获。
  • @Silvestre 的重点是,如果你放弃这些任务,你可能会得到一个没有机会捕捉到的异常。但一切都在答案中。
  • 刚刚测试过:这是目前的好方法:我将为我的异步任务设置 HandleExceptions 扩展。谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-09-27
  • 2012-10-26
  • 2021-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-26
相关资源
最近更新 更多