c# - UseExceptionHandler 不会捕获任务异常?
问题描述
我创建了一个简单的 webapi .net core 3.1 应用程序。
我想捕获所有未处理的异常。所以我根据文档放置了这段代码:
app.UseExceptionHandler(c => c.Run(async context =>
{
var exception = context.Features
.Get<IExceptionHandlerPathFeature>()
.Error;
var response = new { error = exception.Message };
log.LogDebug(exception.Message);
}));
这是我的行动:
[HttpGet]
public IActionResult Get()
{
throw new Exception("this is a test");
}
当这段代码运行时,我确实看到它UseExceptionHandler
正在工作。
但是当我在操作中的代码是:
[HttpGet]
public IActionResult Get()
{
Task.Run(async () =>
{
await Task.Delay(4000);
throw new Exception("this is a test");
});
return Ok();
}
然后UseExceptionHandler
不工作。
但是 - 以下代码确实捕获了任务的异常:
AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) =>
{
Debug.WriteLine(eventArgs.Exception.ToString());
};
问题:
- 为什么任务异常不被识别
UseExceptionHandler
? - 如何捕获所有类型的异常?我应该只依靠
AppDomain.CurrentDomain.FirstChanceException
吗?
注意,我确实禁用了app.UseDeveloperExceptionPage();
解决方案
回答你的问题。
为什么 UseExceptionHandler 无法识别任务异常?
正如评论中已经建议的那样,您不能使用UseExceptionHandler
来捕获在非等待任务中启动的异常。UseExceptionHandler
将您的请求包装在 ASP.NET Core 中间件中。一旦动作返回OK
到客户端,中间件就不再能够捕获从动作内启动的任务中发生的任何异常。
如何捕获所有类型的异常?我应该只依赖 AppDomain.CurrentDomain.FirstChanceException 吗?
如果您愿意,您可以全局捕获异常并以这种方式记录它们。但我不建议你这样做。您需要实现此事件的唯一原因是您正在 Web 请求中启动任务/线程。您无法知道这些任务是否一直在运行(应用程序重新启动、回收等)。如果您希望使用 ASP.NET Core 启动后台任务,则应使用 Worker Services,这是执行此操作的预期方式:
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<MyWorker>();
});
public class MyWorker : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
// Do work
}
catch (Exception e)
{
// Log it?
}
await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
}
}
}
推荐阅读
- invalid-argument - 调用 com 成员函数时 vbscript 中的过程调用或参数无效
- excel - 更改符号颜色的条件格式
- java - 静态方法更改用作参数的变量的值
- r - tidymodels 配方:使用 all_of 选择存储在向量中的变量
- r - 在闪亮的 navbarPage 中插入图
- django - 每个请求中的新 sessionid
- python - 从二进制掩码裁剪图像
- python-3.7 - 如何在 sanic 应用程序中为 tortoise-orm 初始化 db?
- jquery - 使用jQuery查找某些文本,如果存在,则将元素附加到附近的某个元素
- java - 在 Java 中解析来自 C++ 的 protobuf 消息的序列化字符串失败