DBContext ObjectDisposedException: Cannot access disposed object in ASP.NET Core. A common cause of this error is disposing a context..
Issue Description
Entity framework operation gives below runtime error,
System.ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur is you are calling Dispose() on the context, or wrapping the context 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: ‘EmployeeDBContext’.
This error is mostly observed in an application using the EFCore data access layer performing CRUD operation on the Database using DBContext.
Resolution
The issue “Cannot access a disposed of object” I found to be due to improper configuration of operations accessing DBContext (which I have explained below.).
The error I also found to be a bit confusing because I had all the measures mentioned in the error description.
This actually came to me as a surprise as I already had DI implemented with Scope lifetime instance of DBContext appropriately. For DI I had used Constructor injection.
Using AddDbContext(..) ensure that you are registering the DBCOntext as a scoped object. i.e every new request will use the services injected and hence the new DBContext.
Below was my implementation,
services.AddDbContext<EmployeeContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("EmployeeDB"),
sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.EnableRetryOnFailure();
});
});
Below was my method implemented,
If using an API pipeline to configure DBContext objects then it is recommended to use dependency injection (using constructor injection) as shown below
Example:
Choosing the above option also meant it will be an API IoC container that will maintain the lifetime management of DBContext and other objects.
You can also use the EFCore repository – Dependency Injection of DBContext object.
Please remove any using statements if any in the code
(The below code is only intended to be used when you want to manually instantiate and dispose of any DBContext instances.)
using (var employeeContext = new EmployeeContext())
{
employeeContext.Add(value);
await employeeContext.SaveChangesAsync();
}
Instead please use DI using above above-discussed approach. Let’s see below the simplified code.
_employeeContext.Add(value);
await _employeeContext.SaveChangesAsync();
_employeeContext is DI in the constructor.
However if the above alone doesn’t fix the issue, please use additional details that I had to do to resolve the issue.
I had FindAsync which is an asynchronous method but was getting called in the synchronous method, which I had to make it asynchronous (with await keyword ) as below,
Below are the changes that were done to fix the issue,
If you have Async method used in the code then Asynchronous calls propagation should be done to the entire call stack (from start to the end) – Multithreading Async and Await API – Asynchronous Programming
- Marked the method as async
- await the async method call
- Return result as Task<IActionResult> instead of IActionResult
Also, DI using Constructor injection was done as below,
[Route("api/[controller]")]
[ApiController]
public class EmployeeDetailsController : ControllerBase
{
private readonly EmployeeContext _employeeContext;
public EmployeeDetailsController(EmployeeContext context)
{
_employeeContext = context;
}
...
}
If you still face any issues please follow a few additional best practices for EFCore DBContextt listed here in the below article,
Did I miss anything else in these resolution steps?
Did the above steps resolve your issue? Please sound off your comments below!
Happy Coding !!
Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.
That is such an excellent explanation for this error. though it didn’t solve the issue but gave me some hints about the solution.
Man, you saved me, Love you!
Hello Eleazar, thanks for your comments. Glad it helped you.
Thank you , i missed Task in my controller , it save a lot time for me
Hey TechTonic, You are welcome! Glad those guidelines helped you!
Thanks, It saved lots of my time. I forgot to add Task on the controller.
Thanks, Poonam. Glad it helped you!
Thanks a lot, saved my time. I did not use await in my async method
Thanks Arehman. Glad it helped you !
Thanks so much. My issue was the using statement. I have wasted about a day browsing the net trying all different things until I found your solution. Removing the “using” took care of that error.
Thank you Nico for the feedback! Glad it helped you. Cheers!
I totally forgot about a Task in Controller. I had async void. You saved me after 3h debugging, thanks!
Awesome! Glad it helped you!
I want to acces dbcontext DI object after request finished, e.g. do some background task atfet request complete and keep it short.
it says:
Cannot access a disposed object. A common cause of this error is disposing a context 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, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Hi Armen, Thanks for your query. I hope you are following the guidelines mentioned in the article. Please make sure when you use Async followed by await for the end to end call hierarchy. Please refer to additional guidelines – Configuring DbContext in Entity framework ASP.NET Core – Best Practices
Hope this helps.
Me too have same question!
The best way for access injected DbContext in other Task (thread).
Thanks for the query Yshkoury. As explained in the article- DBContext is not thread-safe- Configuring DbContext in Entity framework ASP.NET Core – Best Practices Please make sure to implement concurrency for any parallel access to DBContext.
Thanks , That actually helped me for the same error.
Thank you Lorenzo for confirming it.Appreciate your time.
Thanks for your support.
Hey Navneet – Welcome! Glad it helped you.