31

这是我的问题:我需要在 ApiController 中调用多个第 3 方方法。这些方法的签名是Task DoSomethingAsync(SomeClass someData, SomeOtherClass moreData). 在 ApiController 将数据发送回客户端之后,我希望这些调用继续在后台运行。完成DoSomethingAsync后,我想做一些日志记录,并可能将一些数据保存到文件系统中。我怎样才能做到这一点?我更喜欢使用 asyny/await 语法。

4

5 回答 5

37

好消息,.NET 4.5.2 中有一个名为 QueueBackgroundWorkItem API 的新解决方案。使用起来非常简单:

HostingEnvironment.QueueBackgroundWorkItem(ct => DoSomething(a, b, c));

这是一篇详细描述它的文章。

https://blogs.msdn.microsoft.com/webdev/2014/06/04/queuebackgroundworkitem-to-reliably-schedule-and-run-background-processes-in-asp-net/

这是另一篇文章,其中提到了该线程中未提及的其他一些方法。 http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx

于 2014-10-08T19:29:54.713 回答
26

你几乎从不想这样做。这几乎总是一个大错误。

ASP.NET(和大多数其他服务器)的工作假设是,一旦所有请求完成,就可以安全地关闭您的服务。所以你不能保证你的日志记录会完成,或者你的数据会被写入磁盘。特别是对于磁盘写入,您的写入完全有可能被破坏。

也就是说,如果您绝对确定要实施这种极其危险的设计,您可以使用BackgroundTaskManager我博客中的。

更新:我写了一个博客系列,详细介绍了request-extrinsic code 的正确解决方案。总之,您真正想做的是将请求外部代码移出 ASP.NET。引入持久队列和独立处理器;ASP.NET 控制器操作会将请求放入队列,独立处理器将读取请求并执行它们。这个“处理器”可以是 Azure Function/WebJob、Win32 Service 等。

于 2013-07-10T19:40:08.233 回答
16

Stephen 描述了为什么在 ApiController 中启动基本上长时间运行的即发即弃任务是一个坏主意。

也许您应该创建一个单独的服务来执行那些即发即弃的任务。该服务可以是不同的 ApiController、队列后面的工作人员、可以独立托管并具有独立生命周期的任何内容。

这将使不同任务生命周期的管理变得更加容易,并将长期运行的任务的关注点与 ApiController 的核心职责分开。

于 2013-07-11T13:05:17.680 回答
4

正如其他人指出的那样,不建议这样做。但是,只要有需要就有办法,所以看看IRegisteredObject

也可以看看

http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/

于 2014-07-18T20:50:32.193 回答
1

尽管这个问题已经存在好几年了,但现在最好的解决方案是在这种情况下使用 Singal R。

https://github.com/Myrmex/signalr-notify-progress

于 2020-11-29T21:19:20.580 回答