aspnet / DependencyInjection

[Archived] Contains common DI abstractions that ASP.NET Core and Entity Framework Core use. Project moved to https://github.com/aspnet/Extensions

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ApplicationDbContext ojbect disposed before async function complete

BitBridgeCoin opened this issue · comments

I have two functions within a controller with applicationdbcontext injected, (1) one is for rendering razor page (2) after (1), save some data into database. I tried two ways: task.run(()=>func2) and onactionexecuted, but both failed. I learned that life span of applicationdbcontext object is per request and my case applicationdbcontext object disposed before func2 complete.
I am stuck. Thank you for your help in advance.

First of all, you should avoid doing Task.Run on the server since that schedules the task on the thread pool and threads are a limited resource. Secondly, you need to await the task to get continuation. Otherwise the scope/request may finish before your task is finished

Indeed, it would be helpful to know what the scenario is that you are trying to accomplish. I think @seesharper 's advice is spot on.

the scenario is that I submit a form which would return view(data) with data from DB1, then save cleaning data into DB2. I want the saving data into DB2 to run in background. Thanks!

You need a new db context if you want to do that. The one you are using is tied to the request lifetime.

@davidfowl Thanks! Another db context for the same database and tables? Anyway to share add or update operations on these table set?

@Jingkun-Hu no, you need another instance of the same DbContext.

@davidfowl I call task.run which a method(StockRefreshForDB) that create a new DbContext within it. But I'm worried about what @seesharper mentioned. In addtion, I would like to know (1)alternative writing for task.run (2) exception handling for StockRefreshForDB (3) better way to pass action paramaters to OnActionExecuted (4)ignore re-architecture the code structure. Please see codes below.

   public async Task<IActionResult> StockRefreshOldVersion(int bid, int bbid)
    {
        actionParams.Add("bid", bid);
        actionParams.Add("bbid", bbid);
       
        return View("Index", await StockData(bid));
    }

    //do some background work after return return View("Index", await StockData(bid))
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        var actionName = context.ActionDescriptor.RouteValues["action"];

        if (actionName == "StockRefreshOldVersion")
        {
            Task.Run(async () => await StockRefreshForDB(actionParams["bid"]));
        }
        base.OnActionExecuted(context);
    }

Thanks you guys!