我正在开发将从 WPF 客户端应用程序调用的 ASP.NET Core 8 Web API 端点。该端点需要处理从WPF客户端发送的大量数据。客户端不需要等待处理完成;它只需要知道请求已成功到达 API。
考虑到我们有大约 2,000 个用户使用 WPF 应用程序,我的目标是确保 API 端点快速向客户端返回 200 OK 响应,同时触发长时间运行的任务来处理数据。这样,当服务器处理后台处理时,客户端不会遇到延迟。
这是我到目前为止所做的:
HostedService
进行后台处理。
然而,我面临着HostedService
的挑战。它只需要一个CancellationToken
作为ExecuteAsync
方法的参数,但我需要将端点接收到的数据传递给后台服务进行处理。您能建议实现此模式的最佳方法吗?
具体来说:如何创建可以从 API 端点接收数据的后台服务?
这种方法有什么局限性,针对这种需求是否有更好的替代方案?
[HttpPost]
public async Task<ActionResult> SubmitOrder([FromBody] List<Order> orders)
{
await _transactionProcessor.CreateOrders(orders); // this is the long running task
return Ok();
}
处理器
public class TransactionProcessor : ITractionProcessor
{
public async Task<TransactionResponse> CreateOrders(List<Order> orders)
{
await Task.Delay(5000);
// process orders that takes large amount of time.
throw new NotImplementedException();
}
}
在现实场景中,API 应接收来自客户端的请求,然后将这些消息转发到事件传递系统(例如 RabbitMQ 或 Kafka)。随后,负责消息消费的消费者之一侦听这些队列并开始处理消息。
但是,如果您希望不使用这些系统继续操作,则可以实现“排队托管服务”或中介模式。请务必注意,如果您的 API 崩溃,传输中的任何消息都可能会丢失。如果数据很关键,请考虑将其存储在数据库中以持久保存。 如果您仍然希望将数据传递到后台服务而不使用这些策略,则可以将数据存储在内存中(例如,使用 EF Core 或内存缓存)。然后,在 ExecuteAsync 方法中,您可以继续处理。
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (true)
{
// retrieve data - from memory, db or some static list
var myData = GetDataFromMemory();
if (myData.Length > 0)
{
// do the long running process
}
// make sure delay to prevent excessive CPU usage.
await Task.Delay(5000, stoppingToken);
}
}
很抱歉没有用示例展示所有策略;他们不适合一条评论