Reputation: 171
I have a ASP.Net Core Web API using EF Core for database interaction. DBContext life cycle is managed per Dependency Injection container in startup class:
services.AddDbContext<MyDbContext>(opts =>
opts.UseSqlServer(Configuration.GetConnectionString("MyDbConnectionString")));
In a web GET method, I want to use a background task which process and save data into database but the DBContext is disposed before using it for saving data.
public class MyController : Controller
{
private readonly MyDbContext _context;
public MyController(MyDbContext context)
{
_context = context;
}
[HttpGet("test")]
public async Task<IActionResult> Test(int id)
{
var item = _context.Items.SingleOrDefault(i => i.Id == id);
Task t = new Task(() => SaveAsync(_context));
t.Start();
return Ok(item);
}
private void SaveAsync(MyDbContext context)
{
//processing something for a while
context.SaveChanges();
}
}
The problem is that _context object has been disposed by DI container and I get the error below: 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 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.'
The error is perfectly clear for me but do you know a mean to keep alive the _context in background task?
Upvotes: 2
Views: 1045
Reputation: 5312
If you want to do something like that, I recommend you look into Background tasks with hosted services in ASP.NET Core. However, to get around this error try using RegisterForDispose. There is also an async version.
HttpContext.Response.RegisterForDispose(_context);
Upvotes: 1