I'm facing an issue regarding how to initialize background tasks in a loop in asp.net MVC.
My context is related to competitions. A competition can start as soon as the competitors number is reached, or else after a delay. The user choses how many competitions he wants to join (vm.InscriptionsNumber
), and then calls the following Compete
method.
If there is no existing competition he can join, I have to create one and initialize this new competition's timer, TryStartCompetition
. When called, this method checks if the competition has already started (because the competitors number was reached), and if not, calls the StartCompetition
method.
[HttpPost]
public async Task<ActionResult> Compete(CompetitionsViewModel vm)
{
for (int i = 0; i < vm.InscriptionsNumber; i++)
{
Competition competition = UnitOfWork.CompetitionRepo.Get(...);
if (competition == null) // If there is no existing competition the user can join
{
// Create a new one
competition = new Competition(...);
await UnitOfWork.CompetitionRepo.AddOrUpdate(competition);
// Initialize the start max delay
HostingEnvironment.QueueBackgroundWorkItem(async cancellationToken =>
{
await Task.Delay(Competition.Delay);
await TryStartCompetition(competition);
});
}
else if (competitorsNumberConditionOk)
{
await StartCompetition(competition);
}
// Other stuff...
}
await UnitOfWork.Save();
return PartialView("~/Views/Competitions/Index.cshtml", ViewModel);
}
private async Task TryStartCompetition(Competition compet)
{
// Competition has not started yet
if (!compet.StartDate.HasValue)
{
await StartCompetition(compet);
await UnitOfWork.Save();
}
}
private async Task StartCompetition(Competition compet)
{
// Competition ranking calculation and other stuff here needing async calls
compet.StartDate = DateTime.Now;
}
On the first await
call in StartCompetition
the following exception is raised. I don't know how I should handle it in this particular context.
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.
If vm.InscriptionsNumber
equals 1 everything is okay but as soon as there is actually a loop, the error appears.
If anyone can help me understand why this occurs, I would be really grateful.