【发布时间】:2016-12-19 09:38:42
【问题描述】:
我想在自托管 OWIN 环境中的 ApiController 中运行一个长时间运行的任务(比如 4-5 分钟)。但是,我想在启动该任务后(一旦我开始长时间运行的任务)就发回响应而不等待它完成。这个长时间运行的任务与 HTTP 无关,顺序运行一些可能需要很长时间的方法。
我看了this 的博文,决定试试QueueBackgroundWorkItem。但是,我不确定是否可以在自托管(控制台应用程序)owin 环境中使用此方法或是否有必要使用它。我认为在自托管控制台应用程序中,应用程序本身管理请求并且所有请求都在同一个 AppDomain 中运行(应用程序默认 AppDomain,我们不创建任何新的 appDomain),所以我可以只运行一个长时间运行的任务无需做任何特别的事情,即刻即忘的时尚?
无论如何,当我使用QueueBackgroundWorkItem 时,我总是得到错误:
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Operation is not valid due to the current state of the object.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace>
at System.Web.Hosting.HostingEnvironment.QueueBackgroundWorkItem(Func`2 workItem) at BenchMarkService.SmokeTestController.IsItWorking() in C:\Devel\Code\Projects\BenchMarkService\BenchMarkService\SmokeTestController.cs:line 18 at lambda_method(Closure , Object , Object[] ) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()
</StackTrace>
</Error>
我还发现了关于 SO 的 this 问题,老实说,这对我来说似乎有点令人困惑,因为实现这一目标的唯一方法是 IRegisteredObject?
我只是想在自托管应用程序中运行一个长时间运行的任务,我很欣赏任何关于此的想法。我发现的几乎所有资源和问题都是基于 asp .net 的,我不知道从哪里开始。
【问题讨论】:
-
将任务(在数据库中)排队并让一些服务处理它不是一个选项吗?
-
Hangfire (hangfire.io) 据我所知做了类似的事情。但是,我认为这与问题有点不同。
标签: c# .net asp.net-web-api async-await owin