V
V
vanixachatryan2018-12-22 22:08:13
ASP.NET
vanixachatryan, 2018-12-22 22:08:13

Why is the microservice not starting?

There is a service that implements 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();
            }
        }

An error occurs when starting the project:
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."

on the line _db.CrashGames.Add(game);
How to fix?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexander Yudakov, 2018-12-22
@AlexanderYudakov

Apparently, the scope of the "using (var scope..." block should be extended to the end of the method,
i.e. move the closing bracket to the very bottom.

L
lam0x86, 2018-12-24
@lam0x86

I don't quite understand the meaning of the above code. game.Status = "playing"should it be set immediately, or should you first send several messages to users with an interval of 1 second, and only then the game goes into the playing state? I'm guessing the second one.
Offhand, I see several errors in the code. First, the DoWork method must return a Task, not void. Then the StartAsync method will look like this:

public async Task StartAsync(CancellationToken cancellationToken)
{
    // Хорошим тоном считается использовать CancellationToken, если он есть. 
    // Иначе задачу невозможно будет отменить.
    await DoWork(cancellationToken); 
}

Further, for some reason, you send messages to clients in a separate task, although it would be more logical to do it right there (if my assumption is correct, and we need to transfer the game to playing only after sending all the messages).
Well, as mentioned above, using needs to be expanded to the end of the method.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question