Programmation asynchrone

Les opérations asynchrones évitent de bloquer un thread pendant que la requête est exécutée dans la base de données. Les opérations asynchrones sont importantes pour conserver une interface utilisateur réactive dans des applications client enrichies et peuvent également augmenter le débit dans des applications web dans lesquelles elles libèrent le thread pour servir d’autres requêtes dans des applications web.

En suivant la norme .NET, EF Core fournit des équivalents asynchrones à toutes les méthodes synchrones qui effectuent des E/S. Ceux-ci ont le même effet que la méthode synchrone et peuvent être utilisés avec le C# async et les mots clés await. Par exemple, au lieu d’utiliser DbContext.SaveChanges qui bloque un thread pendant que des E/S de base de données sont effectués. DbContext.SaveChangesAsync peut être utilisé :

var blog = new Blog { Url = "http://sample.com" };
context.Blogs.Add(blog);
await context.SaveChangesAsync();

Pour obtenir plus d’informations, consultez les documentations générales de programmation asynchrone C#.

Avertissement

EF Core ne prend pas en charge les opérations parallèles multiples en cours d’exécution sur la même instance de contexte. Vous devez toujours attendre qu’opération se termine avant de commencer l’opération suivante. Cela est généralement effectué à l’aide du mot-clé await sur chaque opération asynchrone.

Avertissement

L’implémentation asynchrone de Microsoft.Data.SqlClient présente malheureusement certains problèmes connus (par exemple n° 593, n° 601, etc.). Si vous rencontrez des problèmes de performances inattendus, essayez plutôt d’utiliser l’exécution des commandes de synchronisation, en particulier lorsque vous traitez de grandes valeurs de texte ou binaires.

Remarque

EF Core transmet en aval des jetons d’annulation au fournisseur de base de données sous-jacent utilisé (par exemple Microsoft.Data.SqlClient). Ces jetons peuvent être honorés ou pas. Consultez la documentation de votre fournisseur de base de données.

Opérateurs LINQ asynchrones

Pour prendre en charge l’exécution de requêtes LINQ de manière asynchrone, EF Core fournit un ensemble de méthodes d’extension asynchrones qui exécute la requête et renvoie les résultats. Ces équivalents aux opérateurs LINQ synchrones standard incluent ToListAsync, SingleAsync, AsAsyncEnumerable, etc. :

var blogs = await context.Blogs.Where(b => b.Rating > 3).ToListAsync();

Notez qu’il n’existe pas de versions asynchrones de certains opérateurs LINQ comme Where ou OrderBy, car ceux-ci construisent uniquement l’arborescence de l’expression LINQ et n’entraînent pas l’exécution de la requête dans la base de données. Seuls les opérateurs causant une exécution de requête ont des équivalents asynchrones.

Important

Les méthodes d’extension EF Core asynchrones sont définies dans l’espace de noms Microsoft.EntityFrameworkCore. Cet espace de noms doit être importé pour que les méthodes soient disponibles.

Opérateurs LINQ asynchrones côté client

Les opérateurs LINQ asynchrones évoqués ci-dessus peuvent uniquement être utilisés sur des requêtes EF. Vous ne pouvez pas les utiliser avec une requête LINQ to Objects côté client. Pour effectuer des opérations LINQ asynchrones côté client en dehors d’EF, utilisez le package System.Linq.Async. Celui-ci peut être particulièrement utile pour effectuer des opérations sur le client qui ne peuvent pas être traduites pour évaluation sur le serveur.

Dans EF Core 6.0 et version inférieure, le fait de référencer System.Linq.Async entraîne malheureusement des erreurs de compilation d’invocation ambiguë sur des opérateurs LINQ appliqués aux DbSets d’EF, rendant difficile d’utiliser EF et System.Linq.Async dans le même projet. Pour contourner ce problème, ajoutez AsQueryable à votre DbSet :

var groupedHighlyRatedBlogs = await context.Blogs
    .AsQueryable()
    .Where(b => b.Rating > 3) // server-evaluated
    .AsAsyncEnumerable()
    .GroupBy(b => b.Rating) // client-evaluated
    .ToListAsync();