【问题标题】:.NET Core Web API Handling Exceptions after a Response is already sent.NET Core Web API 在响应已发送后处理异常
【发布时间】: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


【解决方案1】:

一个想法是改变你的架构。

Request -> Server

(Server accepts the request with basic validation, but does not completely complete the workload).

Response <-  202 Response (NOT 200).

然后您稍后会回来并投票选出已完成的工作。

这在下面的文章中有更全面的描述。

//startQuote// 解决这个问题的一种方法是使用HTTP 轮询。 轮询对客户端代码很有用,因为它很难提供 回调端点或使用长时间运行的连接。即使当 回调是可能的,额外的库和服务是 required 有时会增加太多额外的复杂性。 //结束引用//

(来自)

https://docs.microsoft.com/en-us/azure/architecture/patterns/async-request-reply

【讨论】:

  • 这基本上已经是我正在做的事情了。更新 repo 状态的匿名函数在客户端已经收到响应后执行。客户端可以轮询另一个端点以获取此匿名函数最终设置的状态。
  • 问题更多是关于底层的错误处理。如果在请求和响应之间执行任何代码并且它抛出了一个没有被明确处理的异常,那么框架似乎会处理它。客户端将获得 500,整个 API 不会崩溃,并且我的 DI 容器中的单例将继续存在。但是,如果在发送响应后执行的匿名函数中抛出异常但未处理,则整个 API 应用程序将崩溃。我希望更好地了解原因
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
相关资源
最近更新 更多