如何在ASP.NET Web API中排队后台任务

app*_*guy 16 c# queue asp.net-web-api

我有一个webapi,旨在以队列方式处理报告.该应用程序采取的步骤如下:

  • 接收内容
  • 将内容映射到对象并将其放入队列
  • 轮询队列中的待处理项目
  • 一次处理队列中的项目

我当时正在考虑使用Entity Framework来创建排队项目的数据库,例如:

public class EFBatchItem
{
    [Key]
    public string BatchId { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateCompleted { get; set; }
    public string BatchItem { get; set; }
    public BatchStatus Status { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我的问题 - 是否有一种更有效的方法,使用NServiceBus,BlockingCollection或ConcurrentQeueue,而不是不断轮询数据库并逐个拉出待处理的项目?我之前没有使用过队列.

一种想法是创建一个任务队列,并在一个单独的线程上处理所有挂起的任务.有点类似于使用线程处理队列的最有效方法,但我想确保我走的是最有效的路由.

编辑:我在这里遇到的一个重要问题是向用户显示进度的最佳方式.一旦用户提交内容,他就会进入新页面,并可以按批次标识符查看状态.MSMQ是必需的,还是NServiceBus,以便通知用户?这似乎是REquest/Acknowledge/Push范式的变体?

tug*_*erk 25

恕我直言,您的ASP.NET Web API应用程序不应该自己运行这些后台任务.它应该只负责接收请求,将其粘贴到队列中(如您所示)并返回指示接收消息成功或失败的响应.您可以使用各种消息传递系统(如RabbitMQ)来实现此方法.

至于通知,您有几个选择.您可以拥有一个客户端可以检查处理是否完成的端点.或者,您可以提供客户端可以订阅的流API端点.这样,客户端就不必轮询服务器; 服务器可以通知连接的客户端.ASP.NET Web API有一个很好的方法.以下博客文章解释了如何:

您还可以将SignalR视为此类服务器的客户端通知.

后台任务对ASP.NET Web API应用程序来说很难的原因是您有责任让AppDomain保持活动状态.这是一个麻烦,尤其是当您在IIS下托管时.以下博客文章解释了我的意思非常好:


Tod*_*odd 6

这是一个NuGet包,它被称为HangFire - https://github.com/HangfireIO/Hangfire.任务仍然存在于apppool回收之外.