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

Mar*_*sen 5 c# asynchronous asp.net-web-api2

我正在开发一个从客户端获取数据的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>(...);
}
Run Code Online (Sandbox Code Playgroud)

和我的NotificationHandler中的方法

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

我在C#世界中相对较新,我不知道是否有更优雅(或正确)的方式.使用这种方法有任何陷阱吗?

Mar*_*lsh 5

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