Udostępnij za pośrednictwem


Programowanie asynchroniczne

Operacje asynchroniczne unikają blokowania wątku podczas wykonywania zapytania w bazie danych. Operacje asynchroniczne są ważne w celu utrzymania dynamicznego interfejsu użytkownika w zaawansowanych aplikacjach klienckich, a także mogą zwiększyć przepływność w aplikacjach internetowych, w których zwalniają wątki do obsługi innych żądań w aplikacjach internetowych.

Zgodnie ze standardem .NET, program EF Core udostępnia asynchroniczne odpowiedniki do wszystkich metod synchronicznych, które wykonują operacje we/wy. Mają one takie same efekty jak metody synchronizacji i mogą być stosowane ze słowami kluczowymi async i await języka C#. Na przykład zamiast używać polecenia DbContext.SaveChanges, co spowoduje zablokowanie wątku podczas wykonywania operacji we/wy bazy danych, można użyć polecenia DbContext.SaveChangesAsync:

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

Aby uzyskać więcej informacji, zobacz ogólną dokumentację programowania asynchronicznego w języku C#.

Ostrzeżenie

Program EF Core nie obsługuje wielu równoległych operacji uruchamianych w tym samym wystąpieniu kontekstu. Przed rozpoczęciem następnej operacji należy zawsze czekać na ukończenie operacji. Zazwyczaj odbywa się to przy użyciu słowa kluczowego await dla każdej operacji asynchronicznej.

Ostrzeżenie

Implementacja asynchronicznego Microsoft.Data.SqlClient niestety ma pewne znane problemy (np. #593, #601i inne). Jeśli występują nieoczekiwane problemy z wydajnością, spróbuj zamiast tego użyć polecenia synchronizacji, szczególnie w przypadku obsługi dużych wartości tekstowych lub binarnych.

Notatka

Program EF Core przekazuje tokeny anulowania do używanego dostawcy baz danych (np. Microsoft.Data.SqlClient). Te tokeny mogą lub nie są honorowane — zapoznaj się z dokumentacją dostawcy bazy danych.

Asynchroniczne operatory LINQ

Aby umożliwić asynchroniczne wykonywanie zapytań LINQ, program EF Core udostępnia zestaw metod rozszerzenia asynchronicznego, które wykonują zapytanie i zwracają wyniki. Te odpowiedniki standardowych, synchronicznych operatorów LINQ obejmują ToListAsync, SingleAsync, AsAsyncEnumerableitp.:

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

Należy pamiętać, że nie ma żadnych asynchronicznych wersji niektórych operatorów LINQ, takich jak Where lub OrderBy, ponieważ tworzą one tylko drzewo wyrażeń LINQ i nie powodują wykonywania zapytania w bazie danych. Tylko operatory, które powodują wykonywanie zapytania, mają odpowiedniki asynchroniczne.

Ważny

Metody rozszerzenia asynchronicznego platformy EF Core są definiowane w przestrzeni nazw Microsoft.EntityFrameworkCore. Aby metody były dostępne, ta przestrzeń nazw musi zostać zaimportowana.

Asynchroniczne operatory LINQ po stronie klienta

W niektórych przypadkach możesz chcieć zastosować operatory LINQ po stronie klienta do wyników pochodzących z bazy danych; Jest to konieczne szczególnie w przypadku konieczności wykonania operacji, której nie można przetłumaczyć na język SQL. W takich sytuacjach użyj AsAsyncEnumerable, aby wykonać zapytanie w bazie danych i kontynuować tworzenie operatorów LINQ po stronie klienta na wynikowym IAsyncEnumerable<T>. Na przykład następujące polecenie wykonuje lokalną funkcję .NET w asynchronicznych wynikach zapytania EF LINQ:

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

Notatka

Operatory LINQ dla IAsyncEnumerable<T> zostały wprowadzone na platformie .NET 10. W przypadku korzystania ze starszej wersji platformy .NET należy odwołać się do pakietu System.Linq.Async.