2013-10-08 30 views
12

Mi piacerebbe solo fare una chiamata a SQL Server e non aspettare un ritorno. Ho una funzione entità importata da una stored procedure che mi piacerebbe chiamare in modo asincrono in questo modo in Entity Framework 6.0.0-rc1. È possibile? Qual è la sintassi?Come si avvia una procedura memorizzata dell'entità in EF6 asincrona e non si attende un ritorno?

Entity Function: RecalculateBudgetNumbers(int id) 
+0

non rimanere bloccati nel Entity-Framework! Puoi usare quei metodi asincroni come puoi usare tutto il resto asincrono. (Task.Run, Thread, async (dal 4.5)) – Marguth

risposta

7

Nuova Task che crea un contesto dati fresco e richiama quella funzione. Basta non aspettare/attendere quel compito. Lascialo correre da solo fino al completamento.

Assicurarsi di registrare gli errori. Non ingoiare le eccezioni perché potrebbero essere bug che vuoi sapere.

In un'impostazione di ASP.NET, tenere presente che il processo di lavoro può essere riciclato in qualsiasi momento, in modo che il lavoro in background possa improvvisamente scomparire (o essere annullato).

+0

Ho aggiunto del codice. Quando provo a rimuovere Wait in RecalculateBudgetNumbersAsync, VS mi avvisa: Poiché questa chiamata non è attesa, l'esecuzione del metodo corrente continua prima che la chiamata sia completata. Prendi in considerazione l'applicazione dell'operatore "Attendi" al risultato della chiamata. Come faccio a lasciarlo funzionare senza aspettare un ritorno? – dirq

+0

Si è in attesa del task in background che ovviamente lo rende non in background ... – usr

+1

@usr ha passato molto tempo a cercare di far funzionare il mio esempio utilizzando prove diverse. I miei bisogni asincroni includevano il salvataggio usando dbcontext. Il tuo commento sull'utilizzo di un nuovo contesto di dati ha aiutato molto. grazie – user1019042

3

Ahh. Ero in Entity Framework land troppo a lungo. Grazie per i suggerimenti. Ecco cosa ha funzionato per me. Vedi qualche problema con questo?

/// <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); 
     } 
    } 

E il mio test (sono in Visual Studio 2012, quindi posso eseguire un test asincrono).

[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()); 
    } 

Dopo suggerimenti da Matt Smith e Usr, ho cambiato RecalculateBudgetNumbersAsync a questo. Spero che questo è quello che intendevano:

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

Non sono necessarie le parole chiave 'async' /' await' in 'RicalcolaBudgetNumbersAsync'. Rimuovili e avrai funzionalità equivalente. –

+0

Una domanda: rilasciando il thread principale e iniziando uno nuovo non diminuirà le prestazioni !? Sembra esserci un sovraccarico nel generare il nuovo thread e poi riprendere in seguito sul primario, quando il nuovo completo. È? – sandiejat

Problemi correlati