Tôi muốn chạy một tác vụ chạy dài (nói 4-5 phút) trong một ApiController trong môi trường OWIN tự lưu trữ. Tuy nhiên tôi muốn gửi một phản hồi lại sau khi bắt đầu nhiệm vụ đó (ngay sau khi tôi bắt đầu nhiệm vụ chạy dài) mà không cần đợi nó kết thúc. Nhiệm vụ chạy dài này không liên quan gì đến HTTP và tuần tự chạy một số phương thức có thể mất rất nhiều thời gian.Tác vụ chạy dài trong ApiController (sử dụng WebAPI, OWIN tự lưu trữ)
Tôi có xem this bài đăng trên blog và quyết định thử xem QueueBackgroundWorkItem
. Tuy nhiên, tôi không chắc chắn nếu nó có thể sử dụng phương pháp này trong môi trường nợ tự lưu trữ (giao diện điều khiển ứng dụng) hoặc cần thiết để sử dụng nó. Trong ứng dụng giao diện điều khiển tự lưu trữ, tôi nghĩ, ứng dụng tự quản lý các yêu cầu và tất cả yêu cầu chạy trong cùng một AppDomain (các ứng dụng mặc định AppDomain, chúng tôi không tạo bất kỳ appDomain mới nào), vì vậy có thể tôi chỉ cần chạy một tác vụ chạy dài trong một thời trang lửa-và-quên, mà không làm bất cứ điều gì đặc biệt?
Dù sao, khi tôi sử dụng QueueBackgroundWorkItem
, tôi luôn nhận được lỗi:
<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>
Ngoài ra tôi thấy this câu hỏi về SO và phải trung thực có vẻ như một chút khó hiểu đối với tôi như là cách duy nhất để đạt được điều đó là IRegisteredObject
hay không?
Tôi chỉ đang cố chạy một tác vụ dài trong ứng dụng tự lưu trữ và tôi đánh giá cao bất kỳ ý tưởng nào về điều đó. Hầu như tất cả các tài nguyên, các câu hỏi tôi tìm thấy đều dựa trên asp .net và tôi không chắc bắt đầu từ đâu.
Không phải là một tùy chọn để xếp hàng tác vụ (trong cơ sở dữ liệu) và để một số dịch vụ xử lý nó? –
Hangfire (https://www.hangfire.io/) thực hiện điều gì đó tương tự như tôi biết.Tuy nhiên, tôi tin rằng điều này hơi khác một chút so với câu hỏi. – Deniz