Compartilhar via


Programação assíncrona

As operações assíncronas evitam o bloqueio de um thread enquanto a consulta é executada no banco de dados. As operações assíncronas são importantes para manter uma interface do usuário responsiva em aplicativos cliente avançados e também podem aumentar a taxa de transferência em aplicativos Web em que eles liberam o thread para atender a outras solicitações em aplicativos Web.

Seguindo o padrão .NET, o EF Core fornece equivalentes assíncronos a todos os métodos síncronos que executam E/S. Eles têm os mesmos efeitos que os métodos de sincronização e podem ser usados com as palavras chaves async e await do C#. Por exemplo, em vez de usar DbContext.SaveChanges, o que bloqueará um thread enquanto a E/S do banco de dados for executada, DbContext.SaveChanges poderá ser usado:

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

Para obter mais informações, consulte os documentos gerais de programação assíncrona do C#.

Aviso

O EF Core não oferece suporte para várias operações simultâneas sendo executadas na mesma instância de contexto. Aguarde sempre a conclusão de uma operação antes de iniciar a operação seguinte. Isso geralmente é feito usando a palavra-chave await em cada operação assíncrona.

Aviso

A implementação assíncrona do Microsoft.Data.SqlClient tem alguns problemas conhecidos (por exemplo, #593, #601 e outros). Se você estiver enfrentando problemas de desempenho inesperados, tente usar a execução de comando de sincronização, especialmente ao lidar com valores binários ou de texto grande.

Observação

O EF Core passa tokens de cancelamento para o provedor de banco de dados subjacente em uso (por exemplo, Microsoft.Data.SqlClient). Esses tokens podem ou não ser respeitados. Consulte a documentação do provedor de banco de dados.

Operadores LINQ assíncronos

Para dar suporte à execução de consultas de forma assíncrona, o EF Core fornece um conjunto de métodos de extensão assíncrona que executam a consulta e retornam resultados. Esses equivalentes aos operadores LINQ padrão e síncronos incluem ToListAsync, SingleAsync, AsAsyncEnumerable, etc.:

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

Observe que não há versões assíncronas de alguns operadores LINQ, como Where ou OrderBy, porque elas só são desenvolvidas na árvore de expressão do LINQ e não fazem com que a consulta seja executada no banco de dados. Somente os operadores que causam a execução da consulta têm equivalentes assíncronos.

Importante

Os métodos de extensão assíncrona do EF Core são definidos no namespace Microsoft.EntityFrameworkCore. Esse namespace deve ser importado para que os métodos sejam disponibilizados.

Operadores LINQ assíncronos do lado do cliente

Os operadores LINQ assíncronos discutidos acima só podem ser usados em consultas do EF; não é possível usá-los com a consulta LINQ to Objects. Para executar operações LINQ assíncronas do lado do cliente fora do EF, use o System.Linq.Async pacote; esse pacote pode ser especialmente útil para executar operações no cliente que não podem ser traduzidas para avaliação no servidor.

No EF Core 6.0 e anteriores, referenciar System.Linq.Async causa erros de compilação de invocação ambíguos em operadores LINQ aplicados aos DbSets do EF; isso dificulta o uso de EF e System.Linq.Async no mesmo projeto. Para contornar esse problema, adicione AsQueryable ao seu DbSet:

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