I would like to run a long running task (say 4-5 minutes) in an ApiController within a self-hosted OWIN environment. However I would like to send a response back after starting that task (as soon as I started the long running task) without waiting it to finish. This long running task has nothing to do with the HTTP and sequentially runs some methods which may take very long.
I have a look at this blog post and decided to give a try to QueueBackgroundWorkItem
. However, I am not sure if it is possible to use this method in a self-hosted (console application) owin environment or necessary to use it. In a self-hosted console application I think, the application itself manage the requests and all request run within the same AppDomain (applications default AppDomain, we do not create any new appDomain), so may be I can just run a long running task in a fire-and-forget fashion, without doing anything special?
Anyway, when I use QueueBackgroundWorkItem
, I always get the error:
<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>
Also I found this question on SO and to be honest it seems a little bit confusing to me as the only way to achieve that is IRegisteredObject
or not?
I am just trying to run a long running task in a self-hosted application and I appreciate any ideas about that. Almost all of the resources, questions I found are based on asp .net and I am not sure where to start.