This is a .NET Razor app. I have an AJAX call in the CSHTML to a onpost method. The OnPost does some DB stuff, then calls a method that I would like to run in its own thread. If I await the method things work, but I need it to go off and do its thing and let user continue on form. It alwaus fails at the _context2.Attach(mo).State EntityState.Modified; with error Cannot access a disposed object. A common cause of this error is disposing a context. I have tried task/thread, changing return type to IactionResult etc.. always same issue. Sorry new to threading in C#. Any Ideas
public async Task<JsonResult> OnPostSignup(MarketOperator MarketOperator, Boolean Confirm = false)
{
Does some DB stuff
_context.Attach(RAExists).State = EntityState.Modified;
await _context.SaveChangesAsync();
//Task.Run(async () => AI_Creation(_context,MarketOperator.MarketDescription,
//MarketOperator.MOID));
Thread t3 = new Thread(() => AI_Creation(_context,
MarketOperator.MarketDescription, MarketOperator.MOID));
t3.Start();
}
public async Task<IActionResult> AI_Creation(AppDbContext context,string idea, int moid)
{
//calls a bunch of open-ai calls which are awaited.. These work
enter code here
AppDbContext _context2 = context;
MarketOperator mo = await _context2.MarketOperator.FirstOrDefaultAsync(ra => ra.MOID == moid);
mo.Keywords = aI_Answers.keywords;
_context2.Attach(mo).State = EntityState.Modified;
await _context2.SaveChangesAsync()
}
That's because EF context is registered as scoped service by default.
What you can do is however, is to create own scope - for that you need to inject IServiceProvider
to your controller.
So you define
private readonly IServiceProvider serviceProvider;
and assign it in contructor.
Then first thing (before serviceProvider
gets disposed) in method you need to create scope:
public async Task<IActionResult> AI_Creation(string idea, int moid)
{
using var scope = serviceProvider.CreateScope();
// you can use resolve context later on like this
using var context = scope.ServiceProvider.GetRequiredService<AppDbContext>();