Programmazione asincrona

Le operazioni asincrone evitano di bloccare un thread mentre la query viene eseguita nel database. Le operazioni asincrone sono importanti per mantenere un'interfaccia utente reattiva in applicazioni client avanzate e possono anche aumentare la velocità effettiva nelle applicazioni Web in cui liberano il thread per gestire altre richieste nelle applicazioni Web.

Seguendo lo standard .NET, EF Core fornisce controparti asincrone a tutti i metodi sincroni che eseguono operazioni di I/O. Questi hanno gli stessi effetti dei metodi di sincronizzazione e possono essere usati con le parole chiave C# async e await . Ad esempio, anziché usare DbContext.SaveChanges, che bloccherà un thread durante l'esecuzione dell'I/O del database, è possibile usare DbContext.SaveChangesAsync:

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

Per altre informazioni, vedere la documentazione generale sulla programmazione asincrona C#.

Avviso

EF Core non supporta l'esecuzione di più operazioni parallele nella stessa istanza di contesto. È sempre necessario attendere il completamento di un'operazione prima di iniziare l'operazione successiva. Questa operazione viene in genere eseguita usando la await parola chiave in ogni operazione asincrona.

Avviso

L'implementazione asincrona di Microsoft.Data.SqlClient presenta purtroppo alcuni problemi noti ,ad esempio #593, #601 e altri. Se si verificano problemi di prestazioni imprevisti, provare a usare l'esecuzione del comando di sincronizzazione, soprattutto quando si usano valori binari o di testo di grandi dimensioni.

Nota

EF Core passa i token di annullamento al provider di database sottostante in uso, ad esempio Microsoft.Data.SqlClient. Questi token possono o non essere rispettati. Consultare la documentazione del provider di database.

Operatori LINQ asincroni

Per supportare l'esecuzione di query LINQ in modo asincrono, EF Core fornisce un set di metodi di estensione asincroni che eseguono la query e restituiscono risultati. Queste controparti agli operatori LINQ standard e sincroni includono ToListAsync, SingleAsync, AsAsyncEnumerablee così via:

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

Si noti che non esistono versioni asincrone di alcuni operatori LINQ, Where ad esempio o OrderBy, perché si compilano solo l'albero delle espressioni LINQ e non causano l'esecuzione della query nel database. Solo gli operatori che causano l'esecuzione di query hanno controparti asincrone.

Importante

I metodi di estensione asincroni di EF Core sono definiti nello spazio dei nomi Microsoft.EntityFrameworkCore. Questo spazio dei nomi deve essere importato affinché i metodi siano disponibili.

Operatori LINQ asincroni lato client

Gli operatori LINQ asincroni descritti in precedenza possono essere usati solo nelle query EF. Non è possibile usarli con query LINQ to Objects sul lato client. Per eseguire operazioni LINQ asincrone sul lato client all'esterno di ENTITY, usare il System.Linq.Async pacchetto. Questo pacchetto può essere particolarmente utile per eseguire operazioni sul client che non possono essere convertite per la valutazione nel server.

In EF Core 6.0 e versioni precedenti, il riferimento purtroppo causa errori ambigui di compilazione System.Linq.Async delle chiamate sugli operatori LINQ applicati ai DbSet di EF. In questo modo è difficile usare ef e System.Linq.Async nello stesso progetto. Per risolvere questo problema, aggiungere AsQueryable a DbSet:

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