데이터 계층에서 DbContext를 차례로 사용하는 일부 리포지토리를 사용하는 비즈니스 로직 계층에 일부 코드가 있습니다. 대부분의 코드는 비동기입니다. 내 비즈니스 로직의 어떤 시점에서, 나는 한 번 (Task.WhenAll...)
) 에서 저장소의 여러 비동기 메서드를 호출하고 난 오류로 실행 A second operation started on this context before a previous asynchronous operation completed
EF6에서 작업 완료를위한 DbContext 잠금
견해는, 비즈니스 로직은/치료 방법에 대한 인식해서는 안된다 리포지토리는 자신의 업무를 수행하므로 "기쁘다"면 비동기 작업에 병렬 처리를 사용할 수 있어야합니다.
A second operation
은 previous asynchronous operation
이 완료 될 때까지 대기해야하는 중요한 순간을 비동기식/기다리기 쉬운 방식으로 잠글 수 있기를 바랍니다.
어떻게이 작업을 수행 할 수 있습니까?
현재 작업을 arround : 사용 도
var postsResult = await _IUserLogic.GetActivePostsAsync();
var usersResult = await _IUserLogic.SearchUsersWithPostAsync(viewModel.Name, viewModel.PostId);
코드 존재하지 않는 TPL 같은을 기다리고 Task.WhenAll을 잊지는 각 스레드가 자신의 DbContext을 필요로
var postsTask = _IUserLogic.GetActivePostsAsync();
var usersTask = _IUserLogic.SearchUsersWithPostAsync(viewModel.Name, viewModel.PostId);
await Ask.WhenAll(postsTask , usersTask);
var postsResult = postsTask.Result;
var usersResult = usersTask.Result;
'DbContext'는 스레드로부터 안전한 객체가 아닙니다. 요청 당 별도의 인스턴스가 필요합니다. 쉬운 방법 중 하나는 conn 문자열을 repo에 삽입하고 요청에 따라 컨텍스트를 생성하는 것입니다. 잠금은 요청을 순차적으로 처리하는 또 하나의 방법 일 뿐이므로 요청을 차례대로 기다리는 것과 마찬가지로 여기에서 응답이되지는 않습니다. – JSteward
데이터를 읽는 데 여러 DbContext를 사용하면 메모리가 흐려질 수 있습니다. 그러나 데이터 업데이트가 포함되는 즉시 간섭 (런타임 예외) 될 수 있습니다. 그래서 그것은 나를위한 실행 가능한 해결책이 아닙니다. 잠금 기능을 사용하면 전체적인 생각을 실제로 순차적으로 만들 수는 있지만 Business Logic에서는이를 처리 할 필요가 없습니다 (사용하기가 쉽다고해도 모든 곳에서 나타나야 함을 의미하지는 않습니다). 내일 데이터 원본을 병렬 읽기 (ADO.Net?)를 지원하는 것으로 변경하면 비즈니스 논리가 전체 인수 분해 없이도이를 활용하게됩니다. –
비동기 잠금을 원한다면 [SemaphoreSlim] (https://docs.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim?view=netframework-4.7.1) – JSteward