비동기 프로그래밍Asynchronous Programming

비동기 작업은 쿼리가 데이터베이스에서 실행 되는 동안에는 스레드를 차단 하지 않습니다.Asynchronous operations avoid blocking a thread while the query is executed in the database. 비동기 작업은 풍부한 클라이언트 응용 프로그램에서 응답성이 뛰어난 UI를 유지 하는 데 중요 하며, 웹 응용 프로그램에서 다른 요청을 처리 하기 위해 스레드를 해제 하는 웹 응용 프로그램의 처리량을 높일 수도 있습니다.Async operations are important for keeping a responsive UI in rich client applications, and can also increase throughput in web applications where they free up the thread to service other requests in web applications.

.NET standard를 따라 EF Core는 i/o를 수행 하는 모든 동기 메서드에 비동기 대응 기능을 제공 합니다.Following the .NET standard, EF Core provides asynchronous counterparts to all synchronous methods which perform I/O. 이는 동기화 메서드와 동일한 효과를 가지 며 c # 및 키워드와 함께 사용할 수 async 있습니다 await .These have the same effects as the sync methods, and can be used with the C# async and await keywords. 예를 들어 데이터베이스 i/o를 수행 하는 동안 스레드를 차단 하는 DbContext를 사용 하는 대신 SaveChangesAsync를 사용할 수 있습니다.For example, instead of using DbContext.SaveChanges, which will block a thread while database I/O is performed, DbContext.SaveChangesAsync can be used:

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

자세한 내용은 일반 c # 비동기 프로그래밍 문서를 참조 하세요.For more information, see the general C# asynchronous programming docs.

경고

EF Core는 동일한 컨텍스트 인스턴스에서 실행되는 여러 병렬 작업을 지원하지 않습니다.EF Core doesn't support multiple parallel operations being run on the same context instance. 항상 작업이 완료될 때까지 대기한 후 다음 작업을 시작해야 합니다.You should always wait for an operation to complete before beginning the next operation. 일반적으로 이 작업은 각 비동기 작업에서 await 키워드를 사용하여 수행합니다.This is typically done by using the await keyword on each async operation.

참고

EF Core는 사용 중인 기본 데이터베이스 공급자 (예: Microsoft. SqlClient)로 취소 토큰을 전달 합니다.EF Core passes cancellation tokens down to the underlying database provider in use (e.g. Microsoft.Data.SqlClient). 이러한 토큰은 적용 될 수도 있고 적용 되지 않을 수도 있습니다. 데이터베이스 공급자의 설명서를 참조 하세요.These tokens may or may not be honored - consult your database provider's documentation.

비동기 LINQ 연산자Async LINQ operators

LINQ 쿼리 실행을 비동기적으로 지원 하기 위해 EF Core는 쿼리를 실행 하 고 결과를 반환 하는 비동기 확장 메서드 집합을 제공 합니다.In order to support executing LINQ queries asynchronously, EF Core provides a set of async extension methods which execute the query and return results. 표준 동기 LINQ 연산자에 해당 하는 이러한 항목에는 ToListAsync, SingleAsync, AsAsyncEnumerable 등이 포함 됩니다.These counterparts to the standard, synchronous LINQ operators include ToListAsync, SingleAsync, AsAsyncEnumerable, etc.:

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

Where 또는 OrderBy와 같은 일부 LINQ 연산자에는 비동기 버전이 없습니다. 이러한 연산자는 LINQ 식 트리를 작성 하 고 데이터베이스에서 쿼리를 실행 하지 않기 때문입니다.Note that there are no async versions of some LINQ operators such as Where or OrderBy, because these only build up the LINQ expression tree and don't cause the query to be executed in the database. 쿼리 실행을 유발 하는 연산자만 비동기 대응 합니다.Only operators which cause query execution have async counterparts.

중요

EF Core 비동기 확장 메서드는 Microsoft.EntityFrameworkCore 네임스페이스에 정의됩니다.The EF Core async extension methods are defined in the Microsoft.EntityFrameworkCore namespace. 메서드를 사용하려면 이 네임스페이스를 가져와야 합니다.This namespace must be imported for the methods to be available.

클라이언트 쪽 비동기 LINQ 연산자Client-side async LINQ operators

위에서 설명한 비동기 LINQ 연산자는 EF 쿼리에만 사용할 수 있으며 클라이언트 쪽 LINQ to Objects 쿼리와 함께 사용할 수 없습니다.The async LINQ operators discussed above can only be used on EF queries - you cannot use them with client-side LINQ to Objects query. EF 외부에서 클라이언트 쪽 비동기 LINQ 작업을 수행 하려면 system.string 패키지를 사용 합니다. 이 패키지는 서버에서 평가를 위해 변환할 수 없는 클라이언트에서 작업을 수행 하는 데 특히 유용할 수 있습니다.To perform client-side async LINQ operations outside of EF, use the System.Interactive.Async package; this package can be especially useful for performing operations on the client that cannot be translated for evaluation at the server.

아쉽게도 System.object를 참조 하면 EF의 DbSets에 적용 된 LINQ 연산자에서 모호한 호출 컴파일 오류가 발생 합니다. 이렇게 하면 동일한 프로젝트에서 EF와 System.object를 모두 사용 하기 어렵습니다.Unfortunately, referencing System.Interactive.Async causes ambiguous invocation compilation errors on LINQ operators applied to EF's DbSets; this makes it hard to use both EF and System.Interactive.Async in the same project. 이 문제를 해결 하려면 DbSet에 AsQueryable 수 있는를 추가 합니다.To work around this issue, add AsQueryable to your DbSet:

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