我将现有的自托管WCF服务移植到IIS托管的Web API。
服务旨在执行长时间运行的操作,客户端(桌面应用程序)可以启动操作,并等待结果,或者断开服务(甚至关闭),然后再返回结果。
目前,WCF服务有此类联系(不允许会话):
public interface IMyServiceContract
{
// this initiates the action and returns the action id
int StartAction(ActionParams actionParams);
// this allows client to query action status (running, completed, faulted)
ActionStatus GetActionStatus(int actionId);
// this allows client to download action result, if action was completed
ActionResult GetActionResult(int actionId);
}
ActionParams
和ActionResult
是一些数据合同,其中包含输入参数和结果值(它不重要,问题上下文中的内容)。
StartAction
方法创建操作ID,通过Task.Factory.StartNew
启动任务,然后返回。客户端定期轮询服务,调用GetActionStatus
方法,如果已完成,客户端将使用GetActionResult
下载结果。
注意,该用户可以启动操作,并关闭计算机,运行客户端应用程序, 但后来他可以下载动作结果。
问题。使用Web API执行此类操作的方法是什么?
我已经在SO上阅读了一些问题,并在asp.net上阅读了教程,但是样本构建得非常相似:它们实现了一种等待的方法并调用异步API(例如,来自EF 6)。到目前为止,据我所知,这并不允许场景"断开连接并下载结果"。
此外,Stephen Cleary发表的this帖子说:
这就是为什么ASP.NET的一个原则是避免使用线程 池线程(ASP.NET提供给你的请求线程除外) 课程)。更重要的是,这意味着ASP.NET应用程序 应该避免使用Task.Run。
我错过了什么吗?
答案 0 :(得分:2)
我使用Hangfire.io进行长时间运行的任务。 Hangfire使用数据库并确保执行任务,即使重新启动了网站(或应用程序池)。
它提供了一个非常简单的API:
BackgroundJob.Enqueue(() => LongRunningTask());
它允许您安排后续执行任务或重复执行任务:
BackgroundJob.Schedule(
() => LongRunningTask(),
TimeSpan.FromDays(7));
RecurringJob.AddOrUpdate(
() => LongRunningTask(),
Cron.Daily);
来自其网站的声明:
仅在成功执行时才从存储中删除后台作业。应用程序重启后,突然中止的作业将被重新排队 创建作业后,即使主机进程已终止,也至少会执行一次。