Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

509
Vistas
BackgroundService Graceful Shutdown - Complete work and write to DB

I have a Background Worker implementing the BackgroundService (provided by MS).

See this simple implementation:

public class MyService : BackgroundService {

    private readonly MyDbContext _context;

    public MyService(MyDbContext context) {
        //...
    }
    
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        try {
            while (true)
            {
                stoppingToken.ThrowIfCancellationRequested();
                // Do some work
            }
        } catch(OperationCancelledException) {
            _context.Add(new MyLogMessage(){ Error = "MyService cancelled!" });
            _context.SaveChanges();
        }
        // ...
    }
}

When the graceful shutdown (in console: CTRL+C) is requested the catch block is triggered, and also the SaveChanges() seems to be executed. But, sometimes the error is stored into the database and the most of the time it is not. Also the EntityFramework is printing an insert statement on the console, but the log is not in the db. I assume that the shutdown is happening faster then writting the data to the DB? Can anyone give me a hint how to handle this situation and store the error into the database?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

The reason why the log entry doesn't appear in the database is that the host shutdown period is lower than what it takes to process a task in a while loop and send a log to the database. The default timeout is 5 seconds.

What you could do, is to increase the timeout to a larger value, for example a minute a two:

services.Configure<HostOptions>(
    opts => opts.ShutdownTimeout = TimeSpan.FromMinutes(2));

Make sure to let enough time for a service to finish the iteration inside a while loop and log the message.

Please check Extending the shutdown timeout setting to ensure graceful IHostedService shutdown for more details.

over 4 years ago · Santiago Trujillo Denunciar

0

It seems like the stoppingToken isn't cancelled as expected when the application shuts down. I managed to get around this using IHostApplicationLifetime and a new field where I can store if a shutdown is in progress.

public class TestService : BackgroundService {
    private readonly IHostApplicationLifetime _lifetime;
    private readonly ILogger<TestService> _logger;

    private bool _shutownRequested;

    public TestService(IHostApplicationLifetime lifetime, ILogger<TestService> logger) {
        _lifetime = lifetime;
        _logger = logger;
    }

    public override Task StartAsync(CancellationToken cancellationToken) {
        _lifetime.ApplicationStopping.Register(OnShutdown);
        return Task.CompletedTask;
    }

    private void OnShutdown() {
        _shutdownRequested = true;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
        try {
            while(true) {
                stoppingToken.ThrowIfCancellationRequested();
                if(_shutdownRequested) {
                    throw new OperationCanceledException();
                }

                await Task.Delay(100, CancellationToken.None);
            }
        } catch(OperationCanceledException) {
            _logger.LogWarning("TestService canceled");
        }
    }
}

Now it might be better to now throw a new exception there, but as an example it will do.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda