DbContext for background tasks via Dependency Injection
To breakdown your questions:
what is the best way to handle this situation?
It's not ideal for the API to handle the long-running tasks. You can delegate the process to a background application
Should I make the AppDbContext singleton?
The dbContext should not be singleton in a web application scenario as it can pose problems like managing transactions.
what is the best way to handle this situation?
breakdown the various services/process:
- The API that will take a file. Ideally the API should just take the file as input and persist it to disk or to database.
- A service that will process the file. Create this component/service as a separate library. Then consume this library from a console app. This way you can profile the performance. Make it fire and forget method by making it async method. This way you have flexibility of reusing your code.
- If you don't expect a lot of file uploads, you can reuse the library at your API controller and execute the method using QueueBackgroundWorkItem. See here for reference: http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx
Should I create a new instance of AppDbContext in the ProcessImport method, and pass it along?
Since it is not thread-safe, create and use a separate instance of your dbContext class in each thread.
I have read DbContext is not thread safe, so is that a good approach?
For an in-depth guide of using EF dbContext, checkout this blog: http://mehdi.me/ambient-dbcontext-in-ef6/
You should pass IServiceScopeFactory
instance (it's singleton) into your task.
Inside task, when data arrives, you should create new CreateScope()
and request services from that scope. When data process finishes - dispose this scope (but hold reference to IServiceScopeFactory
for next run).
See this for example. I run small and fast tasks with this library.
For heavy / long running tasks, as Gert wrote, don't rely that your task will always run to completion. Be ready for restart, be ready for re-processing of the same data.