1

Closed

DbConcurrencyException when using extension method SingleAsync and Task.WhenAll

description

Hi,
            var interviewTasks = new List<Task<Interview>>();

            foreach (var interview in interviews)
            {
                var interviewTask = _context.InterviewRepository.GetIncludingByName(
                                    e => e.InterviewId == interview.InterviewId,
                                    null,
                                    "InterviewCategories",
                                    "InterviewCategories.Category")
                                    .SingleAsync();

                interviewTasks.Add(interviewTask);

            }

            await Task.WhenAll(interviewTasks);

            foreach (var interviewTask in interviewTasks)
            {
                var interview = interviewTask.Result;
                var categories = interview.InterviewCategories
                    .Select(e => e.Category)
                    .Select(e => e.Name)
                    .ToArray();

                interviews.Find(e => e.InterviewId == interview.InterviewId).Categories = categories;
            }
The exception happens at "await Task.WhenAll".

According to the exception message, I need to call await on each task sequentially. What is the point of having a SingleAsync method if you can't call them concurrently?
A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.
What am I missing?

file attachments

Closed Jun 26, 2013 at 2:19 PM by divega
Resolving and closing as by-design per the explanation above.

comments

omegaluz wrote Jun 19, 2013 at 6:45 PM

From what I understand from doing some web searches, there is no way to accomplish what I'm doing outside of creating a new instance of the context.

This leads me to the question, why support async if you don't support concurrency?

divega wrote Jun 26, 2013 at 2:14 PM

@omegaluz: The main motivation for supporting async in EF is to enable better server (e.g. Web server) scalability. This is explained in detail in the feature specification. Enabling asynchronous execution of database operations is actually orthogonal to enabling concurrent execution on the same context. In the particular case of server scenarios, using concurrent access could affect scalability negatively as it would mean that in order to process a single request you would be spinning of an arbitrary number of different threads. All the threads would compete for resources such as memory with other threads necessary to server other concurrent requests.

arthernan wrote Feb 16, 2014 at 3:57 PM

@divega database operations spend a significant amount of time waiting for the server. And operation speed can vary significantly as well. There is no reason not to send all requests at the same time. And process them sequentially in the order received. I am not sure if whenall is to generic. But it should be addressed.