Ich würde gerne eine lange laufende Aufgabe (sagen wir 4-5 Minuten) in einem ApiController innerhalb einer selbst gehosteten OWIN-Umgebung ausführen. Ich möchte jedoch eine Antwort zurücksenden, nachdem ich diese Aufgabe gestartet habe (sobald ich die lange laufende Aufgabe gestartet habe), ohne darauf zu warten, dass sie beendet wird. Diese lange laufende Aufgabe hat nichts mit dem HTTP zu tun und führt sequentiell einige Methoden aus, die sehr lange dauern können.Lange laufende Aufgabe in ApiController (mit WebAPI, selbst gehosteten OWIN)
Ich sehe this Blog-Post und beschlossen, einen Versuch zu QueueBackgroundWorkItem
geben. Ich bin mir jedoch nicht sicher, ob es möglich ist, diese Methode in einer selbst gehosteten (Konsolenanwendung) Umgebung zu verwenden oder sie zu verwenden. In einer selbst gehosteten Konsolenanwendung, denke ich, verwaltet die Anwendung selbst die Anfragen und alle Anfragen laufen innerhalb der gleichen AppDomain (Anwendungen Standard-AppDomain, erstellen wir keine neue appDomain), also kann ich nur eine lange laufende Aufgabe in ausführen eine Feuer-und-Vergessen-Mode, ohne etwas Besonderes zu machen?
Wie auch immer, wenn ich QueueBackgroundWorkItem
verwenden, erhalte ich immer die Fehlermeldung:
<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>
Ich fand auch this Frage auf SO und um ehrlich zu sein es ein wenig verwirrend für mich als den einzigen Weg scheint das zu erreichen ist IRegisteredObject
oder nicht?
Ich versuche nur, eine lange laufende Aufgabe in einer selbst gehosteten Anwendung zu laufen, und ich schätze irgendwelche Ideen darüber. Fast alle Ressourcen, Fragen, die ich gefunden habe, basieren auf asp.net und ich bin mir nicht sicher, wo ich anfangen soll.
Ist es nicht eine Option, die Aufgabe (in der Datenbank) in die Warteschlange einzureihen und einen Dienst behandeln zu lassen? –
Hangfire (https://www.hangfire.io/) macht etwas ähnliches, soweit ich weiß.Ich glaube jedoch, dass dies ein bisschen anders ist als die Frage. – Deniz