2012-11-12 39 views
5

Ho visto una nuova funzione in EF6, i metodi asincroni. Trovo un esempioQual è la differenza tra questa chiamata asincrona in EF?

questo primo modo è chiamata normale, con EF5 ad esempio:

public Store FindClosestStore(DbGeography location) 
{ 
    using (var context = new StoreContext()) 
    { 
     return (from s in context.Stores 
      orderby s.Location.Distance(location) 
      select s).First(); 
    } 
} 

E la nuova chiamata, con il metodo asincrono in EF6.

public async Task<Store> FindClosestStore(DbGeography location) 
{ 
    using (var context = new StoreContext()) 
    { 
     return await (from s in context.Stores 
      orderby s.Location.Distance(location) 
      select s).FirstAsync(); 
    } 
} 

Tuttavia, posso effettuare le seguenti operazioni (la syntaxis è ca., lo faccio a memoria):

public async Task<Store> MyAsyncMethod(DbGeography location) 
{ 
    return await Task.Run(() => FindClosestStore()); 
} 

Cioè, che posso usare Task.Run per chiamare il primo metodo, non è asincrono, aspettare il risultato. Al momento, è il modo in cui uso per chiamare qualsiasi metodo asincrono, non solo EF. Anche questa è una chiamata asincrona o la vera chiamata asincrona è quando utilizzo il metodo asincrono EF6?

Perché sono necessari i metodi asincroni nella nuova versione di EF6? Solo per semplicità?

+0

async e await sono lo zucchero sintattico, nuovo in .Net 4.5, puoi fare lo stesso con Task con ContinueWith –

risposta

9

La differenza qui è come il codice attende.

In di questo codice:

public async Task<Store> FindClosestStore(DbGeography location) 
{ 
    using (var context = new StoreContext()) 
    { 
     return await (from s in context.Stores 
      orderby s.Location.Distance(location) 
      select s).FirstAsync(); 
    } 
} 

EF emetterà una query sul database, e ritorno.

Una volta restituito il risultato, l'attività verrà completata e il blocco Attesa continuerà ad essere eseguito.

Cioè, non c'è thread in. NET che è in attesa della risposta. C'è (si spera) un callback di livello inferiore dal driver db che notifica .NET quando il risultato è arrivato.

(Questo è almeno come altri asincrono funziona IO NET, e presumo lo stesso per ADO.NET asincrona)

Nell'altro caso:

public async Task<Store> MyAsyncMethod(DbGeography location) 
{ 
    return await Task.Run(()=> FindClosestStore()); 
} 

Ci sarà un filo aspettando la risposta dal DB. cioè, avrai IO di blocco ma sarà nascosto al consumatore con il tuo trucco task.run.

Entrambi i casi si comportano allo stesso modo per il consumatore, la differenza è che si stanno utilizzando risorse nell'ultimo esempio.

+0

Penso che l'uso di async/await eviti la necessità di usare un nuovo thread. A volte viene creato e talvolta no (dipende dalla sutiazione). In effetti, con WCF, viene utilizzato il modello async/await per rilasciare le risorse mentre la richiesta viene servita. Con EF funzionerebbe allo stesso modo, liberare le risorse mentre la richiesta sta facendo? –

+2

Nell'ultimo esempio di codice, ci sarà un thread di blocco perché usa i metodi EF asincroni. anche se avvolgi quella chiamata in un blocco asincrono/attendi. questo è. "FindClosestStore()" bloccherà un thread dietro le scene –

+0

e questo non si verifica in WCF quando viene utilizzato async/await? c'è un modo per usare async con EF5? –

Problemi correlati