webapi 2 - 如何正确调用长时间运行的方法异步/在新线程中,并将响应返回给客户端

本文关键字:线程 客户端 返回 响应 新线程 何正确 调用 长时间 运行 异步 方法 | 更新日期: 2023-09-27 18:35:07

我正在开发一个从客户端获取数据并保存以供以后使用的web-api。现在我有一个需要知道所有事件的外部系统,所以我想在我的 web-api 中设置一个通知组件。

我所做的是,保存数据后,我在新组件中执行SendNotification(message)方法。同时,我不希望我的客户等待,甚至不知道我们正在发送通知,所以我想尽快向我的客户返回201 Created / 200 OK响应。

是的,

这是一个即发即弃的场景。我希望通知组件处理所有异常情况(如果通知失败,api 的客户端根本不关心)。

我尝试使用 async/await ,但这在 web-api 中不起作用,因为当请求线程终止时,异步操作也会这样做。

所以我看了看Task.Run().

我的控制器如下所示:

public IHttpActionResult PostData([FromBody] Data data) {
    _dataService.saveData(data);
    //This could fail, and retry strategy takes time.
    Task.Run(() => _notificationHandler.SendNotification(new Message(data)));
    return CreatedAtRoute<object>(...);
}

以及我的通知处理程序中的方法

public void SendNotification(Message message) {
    //..send stuff to a notification server somewhere, syncronously.
}

我在 C# 世界中相对较新,我不知道是否有更优雅(或更合适)的方式来做到这一点。使用这种方法有什么陷阱吗?

webapi 2 - 如何正确调用长时间运行的方法异步/在新线程中,并将响应返回给客户端

这真的取决于多长时间。 您是否研究过QueueBackgroundWorkItem的可能性,详见此处。 如果你想实现一个非常快的触发并忘记了,你可能还需要考虑一个队列来弹出这些消息,以便你可以立即从控制器返回。 然后,您必须有一些东西来轮询队列并发送通知,即计划任务,Windows服务等。 IIRC,如果 IIS 在任务期间回收,则进程将被终止,而对于 QueueBackgroundWorkItem 有一个宽限期,ASP.Net 将让工作项完成其作业。

我会看看Hangfire。它相当容易设置,它应该能够在您的 ASP.NET 进程中运行,并且很容易迁移到独立进程,以防您的 IIS 负载突然增加。不久前,我尝试了Hangfire,但处于独立模式。它有足够的文档和易于理解的API。