Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 17 de octubre de 2017
Puedes encontrar una versión actualizada de este post, que describe una forma mejor de hacerlo:
https://www.variablenotfound.com/2018/05/implementando-mas-facilmente-background.html

ASP.NET Core Es relativamente frecuente encontrar aplicaciones en las que necesitamos disponer de un proceso en background ejecutándose de forma continua. Hace poco hablábamos de IApplicationLifetime, un servicio del framework que nos permitía introducir código personalizado al iniciar y detener las aplicaciones, y probablemente habréis pensado que éste sería un buen sitio para gestionar el inicio y finalización de estas tareas en segundo plano.

Y aunque es posible, ASP.NET Core proporciona otras fórmulas más apropiadas para conseguirlo: los hosted services. Mediante este mecanismo, podemos crear servicios que serán gestionados por el host, y que serán iniciados y finalizados automáticamente junto con la aplicación.

Servicios alojados con IHostedService

Cogs, Font Awesome by Dave Gandy - http://fortawesome.github.com/Font-Awesome [CC BY-SA 3.0 (https://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons Un hosted service es una clase que implementa el interfaz IHostedService, definido en el espacio de nombres Microsoft.Extensions.Hosting de la siguiente forma:
public interface IHostedService
{
    Task StartAsync(CancellationToken cancellationToken);
    Task StopAsync(CancellationToken cancellationToken);
}
El método StartAsync() será invocado por el host cuando esté listo para iniciar el servicio. StopAsync(), en cambio, será ejecutado cuando la aplicación esté finalizando, con objeto de que podamos hacer un cierre civilizado del mismo, por ejemplo, liberando recursos utilizados, eliminando temporales, etc.

El token que se recibe como argumento en StartAsync() se activará cuando la tarea deba finalizar porque el host va a detener la aplicación, y justo antes de llamar a StopAsync(). En este último caso, el token simplemente indica si la propia tarea de finalización debe ser cancelada; por defecto, el sistema dará unos cinco segundos antes de activar este token, por lo que más o menos será ese el tiempo máximo que tenemos para finalizar la tarea y dejar todo bien limpito.

Veamos una posible implementación de un servicio de este tipo, que simplemente registra cada segundo un contador en el log del sistema:
public class MyBackgroundService : IHostedService
{
    private readonly ILogger<MyBackgroundService> _logger;

    public MyBackgroundService(ILogger<MyBackgroundService> logger)
    {
        _logger = logger;
    }
    public async Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Starting my service...");
        for (var i = 1; !cancellationToken.IsCancellationRequested; i++)
        {
            _logger.LogInformation($"Loop #{i}");
            await Task.Delay(1000);
        }
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Stopping my service...");
        return Task.CompletedTask;
    }
}
Una vez tenemos nuestra implementación del servicio, el siguiente paso para ponerlo en funcionamiento es registrar en el contenedor de dependencias una instancia de nuestra clase, asociada al interfaz IHostedService, como sigue:
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddSingleton<IHostedService, MyBackgroundService>();
    }
    ...
}    
Cuando la aplicación ASP.NET Core arranca, el framework buscará en el contenedor todas las clases asociadas a IHostedService, las instanciará e invocará su método StartAsync(). Es decir, de esta forma tan sencilla podemos añadir tantos servicios en segundo plano como necesitemos en nuestras aplicaciones.

Publicado en Variable not found.