I am using .NET Core 3.1. I want to run some background processing without user having to wait for it to finish (it takes about 1 minute). Therefore, I used Task.Run
like this:
public class MyController : Controller
{
private readonly IMyService _myService;
public MyController(IMyService myService)
{
_myService = myService;
}
public async Task<IActionResult> Create(...)
{
await _myService.CreatePostAsync(...);
return View();
}
}
public class MyService : IMyService
{
private readonly MyDbContext _dbContext;
private readonly IServiceScopeFactory _scopeFactory;
public MyService(MyDbContext dbContext, IServiceScopeFactory scopeFactory)
{
_dbContext = dbContext;
_scopeFactory = scopeFactory;
}
public async Task CreatePostAsync(Post post)
{
...
string username = GetUsername();
DbContextOptions<MyDbContext> dbOptions = GetDbOptions();
Task.Run(() => SaveFiles(username, dbOptions, _scopeFactory));
}
private void SaveFiles(string username, DbContextOptions<MyDbContext> dbOptions, IServiceScopeFactory scopeFactory)
{
using (var scope = scopeFactory.CreateScope())
{
var otherService = scope.ServiceProvider.GetRequiredService<IOtherService>();
var cntxt = new MyDbContext(dbOptions, username);
Post post = new Post("abc", username);
cntxt.Post.Add(post); <----- EXCEPTION
cntxt.SaveChanges();
}
}
}
I recieve the following exception in marked line:
System.ObjectDisposedException: 'Cannot access a disposed object. Object name: 'IServiceProvider'.'
Why does this happen? I used custom constructor (and not scope.ServiceProvider.GetRequiredService<MyDbContext>()
) for MyDbContext because I need to save one additional propery (username) for later use in overriden methods.
public partial class MyDbContext
{
private string _username;
private readonly DbContextOptions<MyDbContext> _options;
public DbContextOptions<MyDbContext> DbOptions { get { return _options; } }
public MyDbContext(DbContextOptions<MyDbContext> options, string username) : base(options)
{
_username = username;
_options = options;
}
... other overriden methods
}
What am I doing wrong?