Dela via


Asynkron programmering

Asynkrona åtgärder undviker att blockera en tråd medan frågan körs i databasen. Asynkrona åtgärder är viktiga för att behålla ett dynamiskt användargränssnitt i omfattande klientprogram och kan också öka dataflödet i webbprogram där de frigör tråden för att hantera andra begäranden i webbprogram.

Efter .NET-standarden tillhandahåller EF Core asynkrona motsvarigheter till alla synkrona metoder som utför I/O. Dessa har samma effekter som synkroniseringsmetoderna och kan användas med nyckelorden C# async och await. I stället för att till exempel använda DbContext.SaveChanges, som blockerar en tråd när databas-I/O utförs, kan DbContext.SaveChangesAsync användas:

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

Mer information finns i de allmänna Asynkrona C#-programmeringsdokumenten.

Varning

EF Core stöder inte flera parallella åtgärder som körs på samma kontextinstans. Du bör alltid vänta tills en åtgärd har slutförts innan du påbörjar nästa åtgärd. Detta görs vanligtvis med hjälp av nyckelordet await för varje asynkron åtgärd.

Varning

Asynkron implementering av Microsoft.Data.SqlClient har tyvärr några kända problem (t.ex. #593, #601och andra). Om du får oväntade prestandaproblem kan du prova att använda körning av synkroniseringskommandon i stället, särskilt när du hanterar stora text- eller binära värden.

Not

EF Core skickar annulleringstoken till den underliggande databasprovidern som används (t.ex. Microsoft.Data.SqlClient). Dessa token kan komma att respekteras eller inte – läs databasleverantörens dokumentation.

Async LINQ-operatorer

För att stödja körning av LINQ-frågor asynkront tillhandahåller EF Core en uppsättning asynkrona tilläggsmetoder som kör frågan och returnerar resultat. Dessa motsvarigheter till standardsynkrona LINQ-operatorer omfattar ToListAsync, SingleAsync, AsAsyncEnumerableosv.:

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

Observera att det inte finns några asynkrona versioner av vissa LINQ-operatorer, till exempel Where eller OrderBy, eftersom dessa endast bygger upp LINQ-uttrycksträdet och inte orsakar att frågan körs i databasen. Endast operatorer som orsakar frågekörning har asynkrona motsvarigheter.

Viktig

EF Core-asynkrona tilläggsmetoder definieras i Microsoft.EntityFrameworkCore namnrymd. Det här namnområdet måste importeras för att metoderna ska vara tillgängliga.

Asynkrona LINQ-operatorer på klientsidan

I vissa fall kanske du vill använda LINQ-operatorer på klientsidan för resultat som kommer tillbaka från databasen. Detta behövs särskilt när du behöver utföra en åtgärd som inte kan översättas till SQL. I sådana fall använder du AsAsyncEnumerable för att köra frågan på databasen och fortsätter att skapa LINQ-operatorer på klientsidan över den resulterande IAsyncEnumerable<T>. Följande kör till exempel en lokal .NET-funktion på de asynkrona resultaten av EF LINQ-frågan:

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)
{
    // ...
}

Not

LINQ-operatorer över IAsyncEnumerable<T> introducerades i .NET 10. När du använder en äldre version av .NET refererar du till System.Linq.Async-paketet.