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

515
Vistas
Apagado correcto de BackgroundService: complete el trabajo y escriba en la base de datos

Tengo un Trabajador de fondo que implementa el Servicio de fondo (proporcionado por MS).

Vea esta implementación simple:

 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(); } // ... } }

Cuando se solicita el apagado correcto (en la consola: CTRL+C), se activa el bloque catch y también parece que se ejecuta SaveChanges() . Pero, a veces, el error se almacena en la base de datos y la mayoría de las veces no. Además, EntityFramework está imprimiendo una instrucción de inserción en la consola, pero el registro no está en la base de datos. ¿Supongo que el apagado está ocurriendo más rápido que escribir los datos en la base de datos? ¿Alguien puede darme una pista sobre cómo manejar esta situación y almacenar el error en la base de datos?

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

0

La razón por la que la entrada de registro no aparece en la base de datos es que el período de apagado del host es inferior al que se necesita para procesar una tarea en un ciclo while y enviar un registro a la base de datos. El tiempo de espera predeterminado es de 5 segundos.

Lo que podría hacer es aumentar el tiempo de espera a un valor mayor, por ejemplo, un minuto a dos:

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

Asegúrese de dejar suficiente tiempo para que un servicio termine la iteración dentro de un ciclo while y registre el mensaje.

Consulte Ampliación de la configuración del tiempo de espera de apagado para garantizar un apagado correcto de IHostedService para obtener más detalles.

over 4 years ago · Santiago Trujillo Denunciar

0

Parece que el token de stoppingToken no se cancela como se esperaba cuando la aplicación se cierra. Logré solucionar esto usando IHostApplicationLifetime y un nuevo campo donde puedo almacenar si hay un apagado en curso.

 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"); } } }

Ahora podría ser mejor lanzar una nueva excepción allí, pero como ejemplo servirá.

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