Den*_*niz 5 .net c# async-await asp.net-web-api owin
我想在自托管的OWIN环境中的ApiController中运行一个长时间运行的任务(比如4-5分钟).但是我想在启动该任务后(在我开始长时间运行的任务时)发回响应,而不等待它完成.这个长时间运行的任务与HTTP无关,并且顺序运行一些可能需要很长时间的方法.
我看看这篇博文,并决定尝试一下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>
Run Code Online (Sandbox Code Playgroud)
我也在SO上发现了这个问题,说实话,这对我来说似乎有点困惑,因为实现这个目标的唯一方法是IRegisteredObject什么?
我只是想在自托管应用程序中运行一个长时间运行的任务,我很欣赏任何有关它的想法.几乎所有的资源,我发现的问题都基于asp.net,我不知道从哪里开始.
自托管 OWIN 应用程序通常是常规的控制台应用程序,因此您可以像在控制台应用程序中执行的操作一样,分拆一些长时间运行的任务,例如:
Task.RunThreadPool.QueueUserWorkItemnew Thread(...).Start()在 IIS 托管的 ASP.NET 应用程序中,不建议使用此类方法,因为应用程序池通常会被回收,因此您的应用程序会经常关闭和重新启动。在这种情况下,您的后台任务将被中止。为了防止(或推迟)这种情况,QueueBackgroundWorkItem已经引入了类似的 API 。
但是,因为您是自托管的并且不在 IIS 中运行,所以您可以只使用上面列出的 API。