使用asp.net webapi和TPL捕获未处理的异常

时间:2015-08-27 23:25:29

标签: c# .net asp.net-web-api exception-handling task-parallel-library

我有一个场景,我在其中创建Tasks作为Webapi调用的一部分。当任务中发生异常时,它不会被捕获,我无法弄清楚如何为此实现全局异常处理程序。

特别是:

如果您认为上述任何一项工作都应该让我知道,我会想出一个可重复的小例子,我正在观察。否则,这样做的正确方法是什么呢?

[HttpGet]
public IQueryable<Thingies> Thingies()
{
    Task.Run(() => { throw new ApplicationException("How do I catch all of these globally?"); });
    return _db.Thingies;
}

我还应该注意,应用程序没有System.Web的依赖关系,我不想介绍它们。

2 个答案:

答案 0 :(得分:1)

使用async-await而不是直接使用Task,异常处理将如下所示:

try
{
  // Asynchronous implementation.
  await Task.Delay(1000);
}
catch (Exception ex)
{
  // Handle exceptions.
}

或者,如果您仍然需要使用任务,请按照此处所述继续使用:How to manage properly an exception in a Task with ContinueWith

答案 1 :(得分:1)

从正在运行的任务中抛出的异常不会被处理。他们被捕获在该任务上,使其出现故障。

处理这些异常的正确方法是等待每个任务,或使用Task.ContinueWith注册延续。但是,如果您需要全局处理程序,则可以使用TaskScheduler.UnobservedTaskException事件。

当任务中有异常时,它会被处理并存储在Task对象上供您观察。如果任务被垃圾收集并且任何代码都没有观察到异常.Net知道它永远不会被观察到(因为你没有对任务的引用)并引发TaskScheduler.UnobservedTaskException事件(在.Net 4.0它也会使应用程序崩溃,并且该行为也可以在较新版本中复制。)

因此,TaskScheduler.UnobservedTaskException的事件处理程序将全局处理从任务中引发的所有异常,但只有在它们被GCed之后(不是立即):

TaskScheduler.UnobservedTaskException += (sender, args) => HandleException(args.Exception);