C# 如何在ASP.NET Web API中对后台任务进行排队

C# 如何在ASP.NET Web API中对后台任务进行排队,c#,asp.net-web-api,queue,C#,Asp.net Web Api,Queue,我有一个webapi,旨在以队列方式处理报告。应用程序采取的步骤如下: 接收内容 将内容映射到对象并将其放入队列 轮询队列中的挂起项目 一次处理一个队列中的项目 我正在考虑使用实体框架来创建排队项目的数据库,例如: public class EFBatchItem { [Key] public string BatchId { get; set; } public DateTime DateCreated { get; set; } public DateTi

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

  • 接收内容
  • 将内容映射到对象并将其放入队列
  • 轮询队列中的挂起项目
  • 一次处理一个队列中的项目
我正在考虑使用实体框架来创建排队项目的数据库,例如:

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; }
}
我的问题-有没有一种更有效的方法,使用NServiceBus、BlockingCollection或ConcurrentQUEUEUE,而不是不断地轮询数据库并逐个提取挂起的项目?我以前从未使用过队列

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

编辑:
我这里的一个大问题是向用户显示进度的最佳方式。一旦用户提交内容,他就会进入一个新页面,并可以通过批处理标识符查看状态。是否需要MSMQ或NServiceBus来通知用户?这似乎是请求/确认/推送范例的一种变体?

嗯,您的ASP.NET Web API应用程序不应该单独运行这些后台任务。它应该只负责接收请求,将其放入队列中(如您所示),并返回指示接收消息成功或失败的响应。您可以使用各种消息传递系统,例如用于此方法的消息传递系统

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

您也可以考虑这种类型的服务器到客户端通知。

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


这是一个NuGet软件包,叫做HangFire-。这些任务甚至在apppool回收之后仍然存在。

我喜欢@Todd的解决方案。为了完整起见,还有一个选项没有提到:

HostingEnvironment.QueueBackgroundWorkItem(cancellationToken =>
{
    // Some long-running job
});
注:

当ASP.NET必须回收时,它会通知后台工作(通过设置CancellationToken),然后等待30秒,等待工作完成。如果后台工作没有在该时间段内完成,工作将神秘地消失

并避免在这里使用带有注入DbContext的服务方法,因为这不起作用

资料来源: 及

如果您使用Asp.net Core,您可以使用。

我的解决方案是在写入数据库的代码部分使用
lock
语句。感谢您的提示-我没有想到这一点,以后可能会引起很多问题:)有没有关于排队方法的想法?我应该费心尝试一个BlockingCollection,还是只是不断的数据库轮询?使用quick editWell更新了问题。后台任务实际上是运行几个ASP.NET函数来自动生成报告。然后你会推荐一个单独的应用程序,并将内容传递给它吗?@pendraggon87你所说的“ASP.NET函数”是什么意思?本质上,我是在接收内容,然后使用互操作库生成word文档。我制作了一个web应用程序,允许用户在输入大量信息后通过点击按钮生成文档,但我现在正在制作一个系统,在这个系统中,我可以通过接收JSON数据生成报告。所以我写了所有的代码来写报告。您是否建议我将该代码放在单独的应用程序中?@pendraggon87我要做的是,我可以通过我的ASP.NET Web API应用程序获取数据,将详细信息粘贴到队列中,然后让工作人员生成word文档。对于通知,我将选择上述选项之一。谢谢!你会建议员工使用BackgroundWorker吗?(我在处理队列等方面没有太多经验。我目前只有项目的EF数据库,并使用该数据库作为队列,基于哪些行具有挂起状态。感谢此链接,我以前从未遇到过它,但可能正是我需要的!