Асинхронные проблемы с фоновыми задачами в цикле

Я столкнулся с проблемой, касающейся инициализации фоновых задач в цикле в asp.net MVC.

Мой контекст связан с соревнованиями. Соревнование может начаться, как только число участников будет достигнуто, или после задержки. Пользователь выбирает, в скольких соревнованиях он хочет участвовать (vm.InscriptionsNumber), а затем вызывает следующее Compete метод.

Если нет никакого существующего соревнования, к которому он может присоединиться, я должен создать его и инициализировать таймер этого нового соревнования, TryStartCompetition, При вызове этот метод проверяет, началось ли соревнование (потому что число участников было достигнуто), и, если нет, вызывает StartCompetition метод.

[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;
}

Во-первых await вызывать StartCompetition возникает следующее исключение. Я не знаю, как я должен справиться с этим в этом конкретном контексте.

Вторая операция началась в этом контексте до завершения предыдущей асинхронной операции. Используйте 'await', чтобы убедиться, что все асинхронные операции завершены, прежде чем вызывать другой метод в этом контексте. Любые члены экземпляра не гарантированно являются потокобезопасными.

Если vm.InscriptionsNumber равно 1, все в порядке, но как только появляется цикл, появляется ошибка.

Если кто-нибудь может помочь мне понять, почему это происходит, я был бы очень благодарен.

0 ответов

Другие вопросы по тегам