简体   繁体   English

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

[英]webapi 2 - how to properly invoke long running method async/in new thread, and return response to client

I am developing a web-api that takes data from client, and saves it for later use. 我正在开发一个从客户端获取数据的web-api,并将其保存以供以后使用。 Now i have an external system that needs to know of all events, so i want to setup a notification component in my web-api. 现在我有一个需要知道所有事件的外部系统,所以我想在我的web-api中设置一个通知组件。

What i do is, after data is saved, i execute a SendNotification(message) method in my new component. 我所做的是,在保存数据后,我在我的新组件中执行SendNotification(message)方法。 Meanwhile i don't want my client to wait or even know that we're sending notifications, so i want to return a 201 Created / 200 OK response as fast as possible to my clients. 同时我不希望我的客户等待甚至知道我们正在发送通知,所以我想尽快向客户返回201 Created / 200 OK响应。

Yes this is a fire-and-forget scenario. 是的,这是一个即发即忘的场景。 I want the notification component to handle all exception cases (if notification fails, the client of the api doesn't really care at all). 我希望通知组件处理所有异常情况(如果通知失败,api的客户端根本不关心)。

I have tried using async/await , but this does not work in the web-api, since when the request-thread terminates, the async operation does so aswell. 我尝试过使用async/await ,但这在web-api中不起作用,因为当请求线程终止时,异步操作也会这样做。

So i took a look at Task.Run() . 所以我看了一下Task.Run()

My controller looks like so: 我的控制器看起来像这样:

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>(...);
}

And the method in my NotificationHandler 和我的NotificationHandler中的方法

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

I am relatively new in the C# world, and i don't know if there is a more elegant(or proper) way of doing this. 我在C#世界中相对较新,我不知道是否有更优雅(或正确)的方式。 Are there any pitfalls with using this method? 使用这种方法有任何陷阱吗?

It really depends how long. 这真的取决于多长时间。 Have you looked into the possibility of QueueBackgroundWorkItem as detailed here . 你看着QueueBackgroundWorkItem的可能性详见这里 If you want to implement a very fast fire and forget you also might want to consider a queue to pop these messages onto so you can return from the controller immediately. 如果你想实现一个非常快速的火灾并忘记你也可能想要一个队列来弹出这些消息,这样你就可以立即从控制器返回。 You'd then have to have something which polls the queue and sends out the notifications ie Scheduled Task, Windows service etc. IIRC, if IIS recycles during a task, the process is killed whereas with QueueBackgroundWorkItem there is a grace period for which ASP.Net will let the work item finish it's job. 然后你必须有一些轮询队列并发出通知的东西,例如计划任务,Windows服务等.IIRC,如果IIS在任务期间回收,则进程被杀死,而QueueBackgroundWorkItem则有ASP的宽限期。 Net会让工作项目完成它的工作。

I would take a look on Hangfire . 我会看看Hangfire It is fairly easy to setup, it should be able to run within your ASP.NET process and is easy to migrate to a standalone process in case your IIS load suddenly increases. 它很容易设置,它应该能够在您的ASP.NET进程中运行,并且很容易迁移到独立进程,以防IIS负载突然增加。 I experimented with Hangfire a while ago but in standalone mode. 我不久前尝试过Hangfire,但是在独立模式下。 It has enough docs and easy to understand API. 它有足够的文档和易于理解的API。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM