How do I kick off an entity stored procedure in EF6 async and not wait for a return?

.net-4.5 async-await c# entity-framework visual-studio-2012

Question

I'd like to just punt a call over to the SQL Server and not wait for a return. I have an imported Entity Function from a Stored Procedure that I'd like to call asynchronously this way in Entity Framework 6.0.0-rc1. Is this possible? What's the syntax?

Entity Function: RecalculateBudgetNumbers(int id)
1
14
10/8/2013 2:32:43 PM

Accepted Answer

Start a new Task that creates a fresh data context and invokes that function. Just don't wait/await that task. Let it run by itself to completion.

Make sure to log errors. Don't swallow exceptions because they might be bugs you want to know about.

In an ASP.NET setting, be aware that the worker process can recycle at any time at all, so your background work can suddenly disappear (or be cancelled).

8
10/8/2013 2:45:10 PM

Popular Answer

Ahh. I was in Entity Framework land too long. Thanks for the tips. Here's what worked for me. Do you see any problems with this?

    /// <summary>
    /// kicks off the LONG RUNNING calculations on a budget to regenerate all pre-cooked numbers.
    /// </summary>
    /// <param name="budgetId">Budget Id</param>
    public async System.Threading.Tasks.Task RecalculateBudgetNumbersAsync(int budgetId)
    {
        await System.Threading.Tasks.Task.Factory.StartNew(() => RecalculateBudgetNumbers(budgetId));
    }

    public static void RecalculateBudgetNumbers(int budgetId)
    {
        //this is static so we don't use the unit of work..
        using (BMTContext ctx = new BMTContext())
        {
            ctx.UpdateLifeOfBudgetNumbers(budgetId);                
            ctx.UpdateIntervalNumbers(budgetId);                
            ctx.UpdateIntervalActivityNumbers(budgetId);
            ctx.UpdateLifeOfBudgetActivityNumbers(budgetId);
        }
    }

And my test (I'm in Visual Studio 2012 so I can do an async test).

    [TestMethod]
    public async System.Threading.Tasks.Task RecalculateBudgetNumbersAsyncTest()
    {
        System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
        timer.Start();
        await repo.RecalculateBudgetNumbersAsync(budgetId);

        System.Console.WriteLine("RecalculateBudgetNumbersAsyncTest milliseconds: " + timer.ElapsedMilliseconds.ToString());
    }

After suggestions from Matt Smith and Usr, I changed RecalculateBudgetNumbersAsync to this. I hope this is what they meant:

    public void RecalculateBudgetNumbersAsync(int budgetId)
    {
        System.Threading.Tasks.Task.Factory.StartNew(() => RecalculateBudgetNumbers(budgetId));
    }


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow