Programación asincrónica

Las operaciones asincrónicas evitan bloquear un subproceso mientras la consulta se ejecuta en la base de datos. Las operaciones asincrónicas son importantes para mantener una interfaz de usuario con capacidad de respuesta en aplicaciones cliente enriquecidas y también pueden aumentar el rendimiento en las aplicaciones web donde liberan el subproceso para atender otras solicitudes en las aplicaciones web.

Según el estándar .NET, EF Core proporciona homólogos asincrónicos a todos los métodos sincrónicos que realizan E/S. Tienen los mismos efectos que los métodos de sincronización y se pueden usar con las palabras clave async y await de C#. Por ejemplo, en lugar de usar DbContext.SaveChanges, que bloqueará un subproceso mientras se realiza la E/S de la base de datos, se puede usar DbContext.SaveChangesAsync:

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

Para obtener más información, consulte los documentos generales de programación asincrónica de C#.

Advertencia

EF Core no admite que varias operaciones en paralelo se ejecuten en la misma instancia de contexto. Siempre debe esperar que se complete una operación antes de iniciar la siguiente. Habitualmente, para esto se usa la palabra clave await en cada una de las operaciones asincrónicas.

Advertencia

Desafortunadamente, la implementación asincrónica de Microsoft.Data.SqlClient tiene algunos problemas conocidos (p. ej, #593, #601 y otros). Si observa problemas inesperados de rendimiento, pruebe a usar la ejecución del comando de sincronización en su lugar, especialmente cuando trabaje con valores binarios o de texto grandes.

Nota:

EF Core pasa los tokens de cancelación al proveedor de base de datos subyacente en uso (por ejemplo, Microsoft.Data.SqlClient). Estos tokens pueden o no respetarse: consulte la documentación del proveedor de bases de datos.

Operadores LINQ asincrónicos

Para admitir la ejecución de consultas LINQ de forma asincrónica, EF Core proporciona un conjunto de métodos de extensión asincrónicos que ejecutan la consulta y devuelven resultados. Estos homólogos del estándar, los operadores LINQ sincrónicos, incluyen ToListAsync, SingleAsync, AsAsyncEnumerable, etc.:

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

Tenga en cuenta que no hay versiones asincrónicas de algunos operadores LINQ, como Where o OrderBy, ya que estos solo compilan el árbol de expresiones LINQ y no hacen que la consulta se ejecute en la base de datos. Solo los operadores que provocan la ejecución de consultas tienen homólogos asincrónicos.

Importante

Los métodos de extensión asincrónicos de EF Core se define en el espacio de nombres Microsoft.EntityFrameworkCore. Es necesario importar este espacio de nombres para que los métodos estén disponibles.

Operadores LINQ asincrónicos del lado cliente

Los operadores LINQ asincrónicos descritos anteriormente solo se pueden usar en las consultas de EF; no se pueden usar con la consulta LINQ to Objects del lado cliente. Para realizar operaciones LINQ asincrónicas del lado cliente fuera de EF, use el paquete System.Linq.Async; este paquete puede ser especialmente útil para realizar operaciones en el cliente que no se pueden traducir para la evaluación en el servidor.

En EF Core 6.0 y versiones inferiores, al hacer referencia a System.Linq.Async desafortunadamente se producen errores de compilación de invocación ambiguos en operadores LINQ aplicados a DbSets de EF; esto dificulta el uso de EF y System.Linq.Async en el mismo proyecto. Para solucionar este problema, agregue AsQueryable a DbSet:

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