控制器动作中的长时间运行方法 - MVC

时间:2014-09-22 10:07:58

标签: c# .net asp.net-mvc asp.net-web-api asp.net-web-api2

我在WebAPI - MVC

中有类似以下的方法
public IActionResult Post(Model model)
{
      ALongRunningMethod();
      return Ok();
}

我有两个选择。

  1. 等待方法完成。但是,如果太久了呢? API超时不是吗?
  2. 使用Tasks在单独的线程中运行它,但返回Ok (200 HTTP Code) immediately?如果在长时间运行的方法中发生了一些异常怎么办?
  3. 完全糊涂了。在这种情况下我该怎么做?

3 个答案:

答案 0 :(得分:5)

从.Net 4.5.2开始,您现在有QueueBackgroundWorkItem来处理ASP.Net中的长时间运行。

答案 1 :(得分:2)

这是Web应用程序中的常见问题。我会创建一个GUID,将其传递给任务,运行任务,传回GUID。与此同时,任务将继续进行。如果您有数据库,则可以从任务中将GUID保存到数据库,以指示某些状态。例如你可以有一个名为'任务'的数据库表。列TaskIDStatus

然后,您可以定期使用GUID检索(轮询)任务的状态。

评论者说,ASP.NET中长时间运行的任务是一个危险的游戏是正确的,因为你无法控制应用程序域的生命周期。

答案 2 :(得分:2)

处理此问题的最佳方法是使用单独的服务来实际执行您要运行的任务,而不是在Web api控制器中运行它们。

让Web API端点向数据库写入一个条目,请求完成一些工作,并从该表读取另一个单独的服务并执行这些长时间运行的任务。

您当然可以提供某种ID,以便您可以根据自己的意愿使用WEB API中的另一个端点查询进度。

这样做的原因以及您可能会遇到的问题是 ASP.NET只知道与请求相关联的代码运行,您希望在一个代码中运行的代码因此,后台线程不会被视为请求的一部分,因此可以在任何时候终止一些请求......

以下是这些风险的一些例子:

  1. 与请求无关的线程中的未处理异常将取消该过程。
  2. 如果您在网络服务器场中运行您的网站,您最终可能会遇到多个同时尝试运行相同任务的应用实例。
  3. 您的网站运行的AppDomain可能由于多种原因而停止运行,并使用它来完成后台任务。如果数据在代码执行过程中发生,这可能会破坏数据。
  4. 有关详细信息,请参阅此页面: http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/

    希望这有帮助。