Asynchronní programování

Asynchronní operace neblokují vlákno během provádění dotazu v databázi. Asynchronní operace jsou důležité pro zachování responzivního uživatelského rozhraní v bohatých klientských aplikacích a můžou také zvýšit propustnost webových aplikací, kde uvolní vlákno pro službu jiných požadavků ve webových aplikacích.

Po standardu .NET poskytuje EF Core asynchronní protějšky pro všechny synchronní metody, které provádějí vstupně-výstupní operace. Tyto efekty mají stejné efekty jako metody synchronizace a lze je použít s jazykem C# async a await klíčovými slovy. Například místo použití DbContext.SaveChanges, který bude blokovat vlákno při provedení vstupně-výstupní operace databáze, dbContext.SaveChangesAsync lze použít:

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

Další informace najdete v obecné dokumentaci k asynchronnímu programování jazyka C#.

Upozorňující

EF Core nepodporuje spouštění více paralelních operací ve stejné instanci kontextu. Před zahájením další operace byste měli vždy počkat na dokončení operace. To se obvykle provádí pomocí klíčového await slova pro každou asynchronní operaci.

Upozorňující

Asynchronní implementace Microsoft.Data.SqlClient bohužel obsahuje některé známé problémy (např. #593, #601 a další). Pokud dochází k neočekávaným problémům s výkonem, zkuste místo toho použít spuštění příkazu synchronizace, zejména při práci s velkými textovými nebo binárními hodnotami.

Poznámka

EF Core předává tokeny zrušení do používaného zprostředkovatele databáze (např. Microsoft.Data.SqlClient). Tyto tokeny mohou nebo nemusí být dodrženy – projděte si dokumentaci poskytovatele databáze.

Asynchronní operátory LINQ

Pro podporu asynchronního spouštění dotazů LINQ poskytuje EF Core sadu asynchronních rozšiřujících metod, které spouští dotaz a vrací výsledky. Mezi tyto protějšky standardních synchronních operátorů LINQ patří ToListAsync, SingleAsync, , AsAsyncEnumerableatd.:

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

Všimněte si, že neexistují žádné asynchronní verze některých operátorů LINQ, například Where nebo OrderBy, protože tyto pouze sestavují strom výrazů LINQ a nezpůsobí spuštění dotazu v databázi. Pouze operátory, které způsobují provádění dotazů, mají asynchronní protějšky.

Důležité

Metody asynchronního rozšíření EF Core jsou definovány v Microsoft.EntityFrameworkCore oboru názvů. Tento obor názvů musí být importován, aby byly dostupné metody.

Asynchronní operátory LINQ na straně klienta

Asynchronní operátory LINQ, které jsme probírali výše, je možné použít pouze u dotazů EF – není možné je použít s dotazem LINQ to Objects na straně klienta. Pokud chcete provádět asynchronní operace LINQ na straně klienta mimo EF, použijte System.Linq.Async balíček. Tento balíček může být užitečný zejména pro provádění operací na klientovi, které nelze přeložit pro vyhodnocení na serveru.

V EF Core 6.0 a nižší, odkazování System.Linq.Async bohužel způsobuje nejednoznačné chyby vyvolání kompilace u operátorů LINQ použitých na dbSets EF. To znesnadňuje použití EF i System.Linq.Async ve stejném projektu. Pokud chcete tento problém obejít, přidejte AsQueryable ho do dbSet:

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