Я хотел бы запустить многолетнюю задачу (скажем, 4-5 минут) в ApiController в собственной среде OWIN. Однако я хотел бы отправить ответ после запуска этой задачи (как только я запустил долговременную задачу), не дождавшись завершения. Эта долговременная задача не имеет ничего общего с HTTP и последовательно запускает некоторые методы, которые могут занять очень много времени.Долгосрочная задача в ApiController (с использованием WebAPI, самообслуживаемого OWIN)
Я смотрю сообщение в блоге 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>
Также я нашел this вопрос о SO и, честно говоря, кажется немного запутанным для меня, как единственный способ достижения этой цели IRegisteredObject
или нет?
Я просто пытаюсь запустить многолетнюю задачу в самостоятельном приложении, и я ценю любые идеи об этом. Почти все ресурсы, которые я нашел, основаны на asp .net, и я не уверен, с чего начать.
Не стоит ли ставить в очередь задачу (в базе данных) и разрешить какой-либо сервис ее обрабатывать? –
Hangfire (https://www.hangfire.io/) делает что-то похожее, насколько я знаю.Тем не менее, я считаю, что это немного отличается от вопроса. – Deniz