Saltar al contenido

Cómo ejecutar BackgroundService en un temporizador en ASP.NET Core 2.1

Amelia, miembro de este staff, nos hizo el favor de escribir esta reseña ya que controla perfectamente este tema.

Solución:

Actualizado el 04-2020, ¡léalo en la parte inferior!

@Panagiotis Kanavos dio una respuesta en los comentarios de mi pregunta pero no la publicó como una respuesta real; esta respuesta está dedicada a él/ella.

Usé un servicio de fondo cronometrado como el de Microsoft docs para crear el servicio.

internal class TimedHostedService : IHostedService, IDisposable

    private readonly ILogger _logger;
    private Timer _timer;

    public TimedHostedService(ILogger logger)
    
        _logger = logger;
    

    public Task StartAsync(CancellationToken cancellationToken)
    
        _logger.LogInformation("Timed Background Service is starting.");

        _timer = new Timer(DoWork, null, TimeSpan.Zero, 
            TimeSpan.FromSeconds(5));

        return Task.CompletedTask;
    

    private void DoWork(object state)
    
        _logger.LogInformation("Timed Background Service is working.");
    

    public Task StopAsync(CancellationToken cancellationToken)
    
        _logger.LogInformation("Timed Background Service is stopping.");

        _timer?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    

    public void Dispose()
    
        _timer?.Dispose();
    

En mi caso hice el _timer llamar asíncrono haciendo new Timer(async () => await DoWorkAsync(), ...).

En el futuro, se podría escribir una extensión que haga que una clase como esta esté disponible en el repositorio de Extensiones porque creo que es bastante útil. Publiqué el enlace del problema de github en la descripción.

Un consejo, si planea reutilizar esta clase para múltiples servicios alojados, considere crear una clase base que contenga el temporizador y un resumen PerformWork() o algo así, la lógica del “tiempo” está solo en un lugar.

¡Gracias por sus respuestas! Espero que esto ayude a alguien en el futuro.

Actualización 04-2020:

No es posible inyectar un servicio con ámbito aquí con el contenedor DI de colección de servicios Core normal, listo para usar. Estaba usando autofac, lo que hizo posible usar servicios con alcance como IClassRepository en el constructor debido a un registro incorrecto, pero cuando comencé a trabajar en un proyecto diferente que usaba solo AddScoped<>(), AddSingleton<>(), AddTransient<>() descubrimos que inyectar cosas con ámbito no funciona porque no está en un contexto con ámbito.

Para utilizar sus servicios de alcance, inyecte un IServiceScopeFactory (Más fácil de probar con) y usar CreateScope() que te permite usar scope.GetService() con un using declaración 🙂

Una forma de lograr esto es usar HangFire.io, esto manejará tareas programadas en segundo plano, administrará el equilibrio entre servidores y es bastante escalable.

Ver trabajos recurrentes en https://www.hangfire.io

Acuérdate de que te brindamos la opción de reseñar tu experiencia si diste con el arreglo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *