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

How to queue background tasks in ASP.NET Web API(如何在 ASP.NET Web API 中对后台任务进行排队)
本文介绍了如何在 ASP.NET Web API 中对后台任务进行排队的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a webapi that is designed to process reports in a queue fashion. The steps the application takes are as follows:

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

我正在考虑使用实体框架来创建排队项目的数据库,例如:

I was thinking to use Entity Framework to create a database of queued items, such as:

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 或 ConcurrentQeueue 是否有比不断轮询数据库并一一提取待处理项目更有效的方法?我以前没用过队列.

My question - Is there a more efficient way, using NServiceBus, BlockingCollection or ConcurrentQeueue, than to constantly poll the database and pull out pending items one by one? I have not used queues before.

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

One thought is to create a queue of tasks, and on a separate thread process all pending tasks. Somewhat similar to Most efficient way to process a queue with threads but I want to ensure that I am going the most efficient route.

我在这里遇到的一个大问题是向用户显示进度的最佳方式.一旦用户提交内容,他就会被带到一个新页面,并可以通过批次标识符查看状态.为了通知用户,是否需要 MSMQ 或 NServiceBus?这似乎是 REquest/Acknowledge/Push 范式的变体?

A big question I have here is the best way to display the progress to the user. Once the user submits content, he gets taken to a new page and can view the status by the batch identifier. Is MSMQ necessary, or NServiceBus, in order to notify the user? This seems like a variation of the REquest/Acknowledge/Push paradigm?

推荐答案

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

IMHO, your ASP.NET Web API application shouldn't run those background tasks by itself. It should only be responsible to receive the request, stick it inside the queue (as you indicated) and return the response indicating the success or failure of the received message. You can use variety of messaging systems such as RabbitMQ for this approach.

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

As for the notification, you have a few options. You can have an endpoint which the client can check whether the processing is completed or not. Alternatively, you could provide a streaming API endpoint which your client can subscribe to. This way, the client doesn't have to poll the server; the server can notify the clients which are connected. ASP.NET Web API has a great way of doing this. The following blog post explains how:

  • 使用 ASP.NET Web API 和 Knockout.js 的原生 HTML5 推送通知

对于这种类型的服务器到客户端通知,您还可以考虑 SignalR.

You can also consider SignalR for this type of server to client notifications.

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

The reason why background tasks are hard for ASP.NET Web API application is that you're responsible to keep the AppDomain alive. This is a hassle especially when you are hosting under IIS. The following blog posts explains really good what I mean:

  • 从 ASP.NET 请求中提前返回
  • 在 ASP.NET 中实现重复后台任务的危险

这篇关于如何在 ASP.NET Web API 中对后台任务进行排队的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)