Asynchrone Programmierung
Asynchrone Vorgänge vermeiden das Blockieren eines Threads, während die Abfrage in der Datenbank ausgeführt wird. Asynchrone Vorgänge sind wichtig für die Beibehaltung einer reaktionsfähigen Benutzeroberfläche in Rich-Client-Anwendungen und können auch den Durchsatz in Webanwendungen erhöhen, in denen sie den Thread freigeben, um andere Anforderungen in Webanwendungen zu verarbeiten.
Nach dem .NET-Standard stellt EF Core asynchrone Gegensätze für alle synchronen Methoden bereit, die E/A ausführen. Diese haben dieselben Effekte wie die Synchronisierungsmethoden und können mit den Schlüsselwörtern C# async
und await
verwendet werden. Statt beispielsweise DbContext.SaveChanges zu verwenden, wodurch ein Thread blockiert wird, während datenbank-E/A ausgeführt wird, kann DbContext.SaveChangesAsync verwendet werden:
var blog = new Blog { Url = "http://sample.com" };
context.Blogs.Add(blog);
await context.SaveChangesAsync();
Weitere Informationen finden Sie in der allgemeinen Dokumentation zur asynchronen C#-Programmierung.
Warnung
EF Core unterstützt nicht mehrere parallele Vorgänge, die in derselben Kontextinstanz ausgeführt werden. Sie sollten immer warten, bis ein Vorgang abgeschlossen ist, bevor Sie den nächsten Vorgang starten. Dies erfolgt in der Regel mithilfe des await
Schlüsselworts für jeden asynchronen Vorgang.
Warnung
Die asynchrone Implementierung von Microsoft.Data.SqlClient hat leider einige bekannte Probleme (z. B. #593, #601und andere). Wenn unerwartete Leistungsprobleme auftreten, versuchen Sie stattdessen, die Ausführung von Synchronisierungsbefehlen zu verwenden, insbesondere bei großen Text- oder Binärwerten.
Anmerkung
EF Core übergibt Abbruchtoken an den zugrunde liegenden Datenbankanbieter (z. B. Microsoft.Data.SqlClient). Diese Token können möglicherweise berücksichtigt werden oder auch nicht – konsultieren Sie die Dokumentation Ihres Datenbankanbieters.
Asynchrone LINQ-Operatoren
Um die Ausführung von LINQ-Abfragen asynchron zu unterstützen, stellt EF Core eine Reihe asynchroner Erweiterungsmethoden bereit, die die Abfrage ausführen und Ergebnisse zurückgeben. Zu diesen Gegenstücken zu den standardmäßigen, synchronen LINQ-Operatoren gehören ToListAsync, SingleAsync, AsAsyncEnumerableusw.:
var blogs = await context.Blogs.Where(b => b.Rating > 3).ToListAsync();
Beachten Sie, dass es keine asynchronen Versionen einiger LINQ-Operatoren wie Where oder OrderBygibt, da diese nur die LINQ-Ausdrucksstruktur erstellen und nicht dazu führen, dass die Abfrage in der Datenbank ausgeführt wird. Nur Operatoren, die die Abfrageausführung verursachen, weisen asynchrone Entsprechungen auf.
Wichtig
Die asynchronen EF Core-Erweiterungsmethoden werden im Microsoft.EntityFrameworkCore
Namespace definiert. Dieser Namespace muss importiert werden, damit die Methoden verfügbar sind.
Clientseitige asynchrone LINQ-Operatoren
In bestimmten Fällen sollten Sie clientseitige LINQ-Operatoren auf Ergebnisse anwenden, die aus der Datenbank stammen; Dies ist insbesondere erforderlich, wenn Sie einen Vorgang ausführen müssen, der nicht in SQL übersetzt werden kann. Verwenden Sie für solche Fälle AsAsyncEnumerable, um die Abfrage in der Datenbank auszuführen, und erstellen Sie weiterhin clientseitige LINQ-Operatoren über den resultierenden IAsyncEnumerable<T>. Im Folgenden wird beispielsweise eine lokale .NET-Funktion für die asynchronen Ergebnisse der EF LINQ-Abfrage ausgeführt:
var blogs = context.Blogs
.Where(b => b.Rating > 3) // server-evaluated (translated to SQL)
.AsAsyncEnumerable()
.Where(b => SomeLocalFunction(b)); // client-evaluated (in .NET)
await foreach (var blog in blogs)
{
// ...
}
Anmerkung
LINQ-Operatoren über IAsyncEnumerable<T> wurden in .NET 10 eingeführt. Wenn Sie eine ältere Version von .NET verwenden, verweisen Sie auf das System.Linq.Async
Paket.