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