【发布时间】:2020-07-10 16:34:21
【问题描述】:
我有一个 .NET Core 3.1 Web API,它公开了对一些长时间运行的操作的访问权限。例如,一个客户端请求 API 执行一些需要一段时间的计算。 API 将该请求委托给注入了 Repo 和 Driver 的 Service。该服务将调用驱动程序并传入一个匿名函数,以便驱动程序返回进度,以便服务可以相应地更新 repo。很简单,像这样:
//throw new Exception("This exception won't cause a crash");
_driver.startCalculation(arg1, arg2, (status) => {
//throw new Exception("This exception will cause a crash");
_repo.updateStatus(status);
});
当匿名函数中的代码执行时,响应已经发送到客户端。
如果在外面发生异常,客户端会收到 500 响应并且服务器会继续存在。然而,在里面,一个异常会导致整个 API 进程崩溃。
我正在寻找任何可以帮助我弄清楚我应该如何处理这个问题的见解。为什么那里的异常会导致全面崩溃?我的第一个想法是只吃匿名函数中的任何异常,但我担心我可能只是掩盖了设计缺陷的症状。
【问题讨论】:
-
你考虑过显而易见的事情吗?执行代码块中的 try/catch。
-
@TomTom 这就是最后一句话所指的。我知道这是我可以做的,但我想知道这是我应该做的还是我错过了一些我不知道的语言/框架功能或最佳实践
-
当你说 WebAPI 时。这意味着 HTTP。对于 HTTP,它意味着一个请求和一个响应。如果您在后台线程上初始化一个长时间运行的操作,则在您从 API 发送响应后将有资格被 GC 收集。如果您正在寻找异步操作的一些实时反馈。你需要网络套接字。或者您可以使用 SignalR。或者您可以使用 BackgroundHostedService 并使用 api 调用来跟踪 BackgroundHostedService 的进度
-
“如果你在后台线程上初始化一个长时间运行的操作,是否有资格被 GC 收集”——不,这绝对不是线程或任务的工作方式,你知道的。 GC 将尊重这些,因为计划开始实际上设置了一个引用。
-
async/await在哪里?猜测async void某处或者你没有catch一个异常await或者不是await方法。需要更多的代码来告诉一些有用的东西。是startCalculationasync?
标签: c# asynchronous exception .net-core