Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

513
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!