2016-10-23 2 views
3

sagen, dass ich die folgenden Schnipsel habe:Kann ich Async/Await mit dbContext verwenden? Wenn ja, wann sollte ich ConfigureAwait (false) verwenden?

using (var db = new dbContext()){ 
    var user = db.Users.Find(3); 
    user.Name = "newName"; 
    var viewModel = GetViewModelAndDoStuffToUser(user); 
    db.SaveChanges(); 
    return viewmodel; 
} 

nun durch den Einsatz von Asynchron/await, die Leistung dieses Schnipsels in großem Umfang zu verbessern, aber ich habe gelesen, dass DbContext nicht „thread-safe“ Ich versuche es. Also bin ich ein wenig verwirrt über:

  1. Ob ich async/await mit Anrufen über DbContext können
  2. Ob oder nicht sollte ich .ConfigureAwait(false) verwenden, wenn ich es tue. Ich habe gelesen, dass dies uns sagt, dass wir den ".NET Context", der von MVC- und WebApi-Controllern benötigt wird, nicht erneut eingeben müssen, aber dies ist die Serviceschicht einer Anwendung, die diese Controller bedient. Ich habe auch gelesen, dass dies Deadlocks verhindert.
  3. Ob oder nicht - in komplizierteren Szenarien - ich Anrufe mit der gleichen Instanz von dbContext unter Verwendung Task.WhenAll()

eine skalierbare, Thread-sicheren Schritt in der richtigen Richtung wäre, der folgende Ausschnitt parallelisieren kann?

using (var db = new dbContext()){ 
    var user = await db.Users.FindAsync(3).ConfigureAwait(false); 
    user.Name = "newName"; 
    var viewModel = await GetViewModelAndDoStuffToUserAsync(user).ConfigureAwait(false); 
    await db.SaveChangesAsync().ConfigureAwait(false); 
    return viewmodel; 
} 

Antwort

3

Kurze Antwort ist "Ja", "Ja" und "Ja".

Lange Antwort ist, dass, obwohl db-Kontext nicht Thread-sicher ist, async/await Konstrukte nicht db Kontext zu anderen Threads ohnehin übergeben, so dass Sie hier sicher sind.

Soweit der Anruf an ConfigureAwait(false) geht, sollten Sie es überall außer UI-Code tun. Da der Datenbankcode selten in der UI-Ebene platziert wird (er wird nie in der UI-Ebene in qualitativ hochwertigem Produktionscode platziert), sollten Sie ConfigureAwait(false) bei jedem asynchronen Aufruf verwenden, den Sie im Backend ausführen.

Schließlich, wenn Sie mehrere Aufgaben mit Aufrufen von async Methoden von Db-Kontext machen, erstellen Sie Co-Routinen. Sie parallelisieren Arbeiten außerhalb Ihres Systems (z. B. gleichzeitige DB-Aufrufe), aber an Ihrem Ende laufen sie nicht gleichzeitig. Dies hält Ihren Datenbankkontext sicher, da alle Änderungen daran sequenziell angewendet werden.

+0

Vielen Dank dafür! Ich habe gerade ein drittes Szenario hinzugefügt, für den Fall, dass Sie einen Moment Zeit haben, es anzugehen. – SB2055

+0

Und - stellt ein 'WebApi Controller' einen" UI Code "dar? Oder sind das nur MVC-Controller/Aktionen? – SB2055

+0

@ SB2055 WebApi Controller benötigt nicht 'ConfigureAwait (true)', nur Desktop-UI benötigt es. – dasblinkenlight

Verwandte Themen