I have the following situation: I have an ASP.NET Core controller (.NET 5.0), which has an Import endpoint. Upon calling this endpoint it gathers some configuration and calls
MyService.Import(...) MyService.Import performs some time-consuming operations - it retrieves data from external endpoints (with paging and retries), and then does some heavy lifting on the database.
The controller method can't afford to wait for the service method to finish. It would simply take too long and the callers of my endpoint would get a timeout error. And it's not supposed to anyway, MyService has its own ways of reporting about the status of the import - via logs. This is supposed to be a fire-and-forget call.
I've tried to achieve this fire-and-forget behavior in the following ways:
Make the service method async and just don't await it. The warning I get from this says "Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the await operator to the result of the call." So I would expect that to be the behavior - the calling (controller) method continues and reaches
return Ok(), while the service method does its thing. This isn't what happens. The controller method just stands still waiting for the service method it ostensibly isn't awaiting.Await the method, but put
ConfigureAwait(false)at the end. Same result as above.Calling the service method on a different thread via
Task.Run(() => MyService.Import(...). This approach actually allows the controller method to finish without waiting for the service method. But this causes errors further down the pipe. Somewhere in the bowels of the code, through many layers of DI-initialized providers and resolvers, something was broken by switching the thread, and I get the following error:System.ObjectDisposedException: 'Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: MyDbContext
Re-working the infrastructure so that it can handle switching threads is probably a project for a week. Is there a way have the controller method return without threading? Or some way to "pass the entire context" to the new thread?
awaiting something doesn't mean "waiting for something"