2012-11-12 5 views
5

Ich habe ein neues Feature in EF6, die asynchronen Methoden gesehen. Ich finde ein Beispiel.Was ist der Unterschied zwischen diesen beiden Async-Aufruf in EF?

Dieser erste Weg ist der normale Aufruf, mit EF5 zum Beispiel:

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

Und der neue Anruf, mit Asynchron-Methode 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(); 
    } 
} 

jedoch ich folgendes tun kann (die Syntaxis ca. ist, ich es durch den Speicher zu tun):

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

ich meine, dass ich Task.Run können die erste Methode aufzurufen, das ist kein async, um das Ergebnis abzuwarten. Im Moment benutze ich Async jede Methode, nicht nur EF. Dies ist auch ein Async-Aufruf oder der wirklich asynchrone Aufruf ist, wenn ich die EF6-Async-Methode verwende?

Warum die asynchronen Methoden in der neuen Version von EF6 benötigt? Nur zur Einfachheit?

+0

async und erwarten sind die syntaktischen Zucker, neu in .Net 4.5, können Sie das gleiche tun von Task mit ContinueWith –

Antwort

9

Der Unterschied hier ist, wie der Code erwartet.

In dem von diesem Code:

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 wird eine Abfrage der Datenbank ausführen, und zurück.

Sobald das Ergebnis zurückgegeben wurde, wird die Aufgabe abgeschlossen und der Warten-Block wird weiter ausgeführt.

Das heißt, in .NET selbst gibt es keinen Thread, der auf die Antwort wartet. Es gibt (hoffentlich) einen Callback der unteren Ebene vom db-Treiber, der .NET benachrichtigt, wenn das Ergebnis angekommen ist.

(Dies ist zumindest, wie andere async IO in .NET arbeitet, und ich nehme an, das gleiche gilt für ADO.NET async)

Im anderen Fall:

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

wird es einen Thread sein Warten auf die Antwort von der DB. Das heißt, Sie haben IO blockiert, aber es wird mit Ihrem Task.run Trick vor dem Verbraucher versteckt werden.

Beide Fälle verhalten sich für den Verbraucher gleich, der Unterschied besteht darin, dass Sie im letzten Beispiel Ressourcen in Anspruch nehmen.

+0

Ich denke, dass die Verwendung von async/erwarten die Notwendigkeit der Verwendung eines neuen Threads vermeiden. Manchmal wird erstellt und manchmal nicht (hängt von der Verwendung ab). Bei WCF wird das async/await-Muster verwendet, um die Ressourcen freizugeben, während die Anforderung bearbeitet wird. Mit EF würde es auf die gleiche Weise funktionieren, die Ressourcen freizugeben, während die Anfrage läuft? –

+2

In dem letzten Codebeispiel wird ein blockierender Thread sein, da es die nicht asynchronen EF-Methoden verwendet. Selbst wenn Sie diesen Aufruf in einen async/await-Block einschließen. das ist. "FindClosestStore()" wird einen Thread hinter den Kulissen blockieren –

+0

und dies tritt nicht in WCF auf, wenn Async/wartet? Gibt es eine Möglichkeit, Async mit EF5 zu verwenden? –

Verwandte Themen