@vanixachatryan

Почему не запускается микросервис?

Имеется сервис реализующий IHostedService, IDisposable:

private GamesContext _db;

        private readonly IServiceScopeFactory _scopeService;
        private Timer _timer;

        public CrashService(IServiceScopeFactory scopeService)
        {
            _scopeService = scopeService;
        }
        

        public Task StartAsync(CancellationToken cancellationToken)
        {
            DoWork();

            return Task.CompletedTask;
        }

public async void DoWork()
        {
            using (var scope = _scopeService.CreateScope())
            {
                _db = scope.ServiceProvider.GetRequiredService<GamesContext>();
                _hubContext = scope.ServiceProvider.GetRequiredService<IHubContext<CrashHub>>();
            }

            Random rand = new Random();
            endCoef = (float)(rand.Next(150) + rand.NextDouble());
            CrashGame game = new CrashGame()
            {
                Status = "wait",
                EndValue = endCoef,
                WinnerId = 0
            };

            _db.CrashGames.Add(game);

            await _db.SaveChangesAsync();

            Task timer = Task.Run(async () => {
                for (int i = interval; interval >= 0; i--)
                {
                    await _hubContext.Clients.All.SendAsync("wait", i);
                    await Task.Delay(1000);
                }
            });

            game.Status = "playing";

            _db.CrashGames.Update(game);

            await _db.SaveChangesAsync();

            bool gameStatus = await UpdateCoefAsync();

            if (gameStatus)
            {
                game.Status = "ended";
                _db.CrashGames.Update(game);

                await _db.SaveChangesAsync();
            }
        }


Вылетает ошибка при запуске проекта:
System.ObjectDisposedException: "Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances."


на строчке _db.CrashGames.Add(game);

Как исправить?
  • Вопрос задан
  • 253 просмотра
Пригласить эксперта
Ответы на вопрос 2
AlexanderYudakov
@AlexanderYudakov
C#, 1С, Android, TypeScript
Судя по всему, область действия блока "using (var scope..." следует расширить до конца метода.
Т.е. перенести закрывающую скобку в самый низ.
Ответ написан
lam0x86
@lam0x86
Я пока не очень понял смысл приведенного кода. game.Status = "playing" должен выставиться сразу, или сначала нужно послать несколько сообщений пользователям с интервалом в 1 секунду, и уже потом игра переходит в состояние playing? Предположу, что второе.
Навскидку, вижу несколько ошибок в коде. Во-первых, метод DoWork должен возвращать Task, а не void. Тогда метод StartAsync будет выглядеть так:
public async Task StartAsync(CancellationToken cancellationToken)
{
    // Хорошим тоном считается использовать CancellationToken, если он есть. 
    // Иначе задачу невозможно будет отменить.
    await DoWork(cancellationToken); 
}

Далее, вы зачем-то отправляете сообщения клиентам в отдельном таске, хотя логичнее было бы сделать это тут же (если моё предположение верно, и нам надо перевести игру в playing только после отправки всех сообщений).
Ну и как сказали выше, using нужно расширить до конца метода.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы