0

I just tried upgrading from EF Core 2 to EF Core 3. Every call I have is an Async Task<> method, but I'm still getting the A "Second operation started, see https://go.microsoft.com/fwlink/?linkid=2097913" error. I know it says to await every method, but doesn't that defeat the purpose of making async calls? Also, why does it work in EF Core 2 and not EF Core 3? If I have to use a diff db context, how can this be done with dependency injection in .net core 3?

// Async method that we will await later.
var softwareServiceCodeTask = _pricingCalcRepo.IsSoftwareServiceCodeAsync(jobsId)

pricingCalcInfo = await GetJobDetailsAsync(jobsId);

        private async Task<PricingCalculationInfo> GetJobDetailsAsync(int jobsId)
        {
            return await (
                   from jobs in _contextProposal.PRP_Jobs
                   join service in _contextProposal.PRP_Service on jobs.ServiceId equals service.ServiceId
                   join proposal in _contextProposal.PRP_Proposal on service.ProposalId equals proposal.ProposalId
                   where jobs.JobsId == jobsId
                   select new PricingCalculationInfo
                   {
                       ContractYear = proposal.ContractYear,
                       BidCrewSize = jobs.BidCrewSize,
                       ServiceCode = service.ServiceCode,
                       Territory = jobs.Territory,
                       TotalPONIs = jobs.TotalPONIs,
                       WeekWorkHours = _appSettings.Value.WeekWorkHours,
                       NonProductiveHoursPerWeek = _appSettings.Value.NonProductiveHoursPerWeek
                   }).FirstAsync();
        }
Godrules500
  • 467
  • 6
  • 25

1 Answers1

0

The first line must be awaited. EF does not allow multiple simultaneous operations to run at the same time. While many queries could potentially be run in parallel, EF doesn't support parallel queries, and basically just cuts them off completely, just in case something would not work properly.

Long and short, you need to await everything that will use an EF context immediately. You cannot let it just run and attempt to make another query.

UPDATE

To be clear, EF has never supported parallel queries. That includes both EF Core and the older EF. However, EF Core previously didn't explicitly stop you from doing so, but the results were never guaranteed. The fact that it didn't explicitly stop you, however, gave many the impression that it was fine, and I think that's why they've now blocked you explicitly. Like I said, it would probably be fine most of the time, but there's edge cases where it can break everything. Since EF doesn't really have a plan for handling those edge cases, it blocks you entirely. You can say that's a failing of EF, and it probably is, but that's just the way it is: you can't run queries in parallel in EF.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • Doesn't that defeat the purpose of it being an async call then? Are there any negative effects to making the db context Transient? – Godrules500 Apr 17 '20 at 13:33
  • No. Async is not the same thing as parallelism, nor is it intended to be. Async is about scale: allowing resources to be used more efficiently. That's it. – Chris Pratt Apr 17 '20 at 13:35
  • And yes, there are negative effects to changing the EF context lifetime. EF uses a number of optimizations that depend on it being somewhat long-lived, at least for the life of the request. Do not make it transient. – Chris Pratt Apr 17 '20 at 13:36
  • So if I had 4 calls, first 3 are db calls that setup the 4th call so they could be ran asynchronously, but the last call needs all 3 pieces of information, what is the best way to handle this? Ideally I'd want to run the first 3 async, and then wait for all tasks to be finished, before calling the 4th call right? – Godrules500 Apr 17 '20 at 13:39
  • They're *all* ran async already. Again, async != parallel. You cannot query EF in parallel, period, so what you're wanting to do is fundamentally impossible. You must await each call inline. – Chris Pratt Apr 17 '20 at 13:52