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 di programmazione asincrona C# generale.
Avvertimento
EF Core non supporta l'esecuzione di più operazioni parallele nella stessa istanza di contesto. È consigliabile attendere sempre il completamento di un'operazione prima di iniziare l'operazione successiva. Questa operazione viene in genere eseguita usando la parola chiave await
per ogni operazione asincrona.
Avvertimento
L'implementazione asincrona di Microsoft.Data.SqlClient purtroppo presenta alcuni problemi noti, ad esempio #593, #601e 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 possono essere rispettati - consultare la documentazione del fornitore del 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 sono presenti versioni asincrone di alcuni operatori LINQ, ad esempio Where o OrderBy, perché creano 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 asincrona 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
In alcuni casi, è possibile applicare operatori LINQ lato client ai risultati restituiti dal database; ciò è necessario soprattutto quando è necessario eseguire un'operazione che non può essere convertita in SQL. In questi casi, usare AsAsyncEnumerable per eseguire la query nel database e continuare a comporre operatori LINQ sul risultato IAsyncEnumerable<T>. Ad esempio, il codice seguente esegue una funzione .NET locale sui risultati asincroni della query LINQ di EF:
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)
{
// ...
}
Nota
Gli operatori LINQ in IAsyncEnumerable<T> sono stati introdotti in .NET 10. Quando si usa una versione precedente di .NET, fare riferimento al pacchetto System.Linq.Async
.