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();
}
Is there a way to continue to tell EF core 3.1 to allow concurrency when I know it is safe. this worked in 2.1 so clearly this cannot be dismissed by simply saying db context has never allowed this by design and closing the question as a duplicate.
The DB context has never allowed that. I've never seen this kind of code work on any version of .NET Core. If it happened to work in 2.x, it was only "working" in the sense that the code was winning its race conditions and thus just getting lucky. Any change in performance - reduced memory, antivirus software, alternate network routing - could have caused this to fail. It's very important to recognize that the code is wrong and always has been.
My app has been running happily in production for a long time. Only after migrating to 3.1 has this become an issue. What has changed?
Probably some timing in the framework.
If this worked before when this 'wasn't allowed by design', is it possible that it is similarly not true now as well?
The race condition still exists. If your code happens to win the race condition, you won't see that exception.
Is this change truly impossible to work around or are there exceptions to the claim that the context doesn't allow this?
There's no workaround to force a dbcontext to work with multiple simultaneous requests. The normal pattern for doing simultaneous requests is to use multiple dbcontexts, one for each simultaneous request.
A DbContext
is cheap to create. By default, if you're injecting them into a scoped service, a new one is created for every request. But you can also create them yourself, while still leveraging .NET Core's DI framework.
Declare your DbContext
in Startup.cs
as you normally would. But the service (you are injecting services into your controllers, right?) that uses your DbContext
can be a singleton instead of scoped, since it doesn't need to be injected with a new DbContext
per-request. The background task started by the service can then use a ScopeFactory
to create contexts as needed:
using (var scope = ScopeFactory.CreateScope())
using (var db = scope.ServiceProvider.GetRequiredService<MyDbContext>())
{
// do stuff with db
}