loading...
Cover image for Dica Rápida: Executando tarefas em background com IHostedService

Dica Rápida: Executando tarefas em background com IHostedService

wsantosdev profile image William Santos ・2 min read

Olá!

Este é mais um post da seção Dica Rápida, e hoje falaremos sobre um recurso bastante útil, mas aparentemente pouco conhecido, do Asp.Net Core: o Hosted Service.

Este recurso é expresso pela interface IHostedService (em inglês) que permite à uma implementação reagir aos eventos de inicialização e encerramento do host da aplicação, permitindo que operações sejam realizadas, por exemplo, quando a aplicação é iniciada.

Antes de mais nada, vamos conhecer a interface:

namespace Microsoft.Extensions.Hosting
{
    public interface IHostedService
    {
        Task StartAsync(CancellationToken cancellationToken);
        Task StopAsync(CancellationToken cancellationToken);
    }
}    
Enter fullscreen mode Exit fullscreen mode

Simples. Não? Vejamos uma implementação bem simples da interface:

namespace Lab.HostedService
{
    public class MyHostedService()
    {
        public Task StartAsync(CancellationToken cancellationToken)
        {
            Console.WriteLine("Host iniciado.");
            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            Console.WriteLine("Host encerrado.");
            return Task.CompletedTask;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Uma vez implementada a interface com alguma operação que desejemos executar ao iniciar a aplicação, que inclusive pode ser uma tarefa de longa duração que durará pelo tempo de vida da aplicação, tudo o que precisamos fazer é incluí-la no pipeline de criação da aplicação, e há duas formas para fazê-lo como podemos ver nos dois exemplos abaixo.

Primeiro, a inclusão de um serviço que apenas reagirá à inicialização ou encerramento de nosso host:

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Lab.HostedService
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(builder =>
                    builder.UseStartup<Startup>()
                )
                .ConfigureServices(services =>
                    services.AddHostedService<MyHostedService>()
                );
    }
}
Enter fullscreen mode Exit fullscreen mode

Em seguida, um exemplo onde um serviço poderia ser invocado em outros pontos da aplicação se necessário:

namespace Lab.HostedService
{
    public class Startup
    {
        ...
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<MyHostedService>();
            services.AddHostedService(services => services.GetService<MyHostedService>());
        }
        ...
    }
}
Enter fullscreen mode Exit fullscreen mode

E pronto!

Um detalhe interessante é que há uma implementação padrão para esta interface, também provida pelo Asp.Net Core, a classe base BackgroundService. Ela nos permite implementar tarefas de longa duração de forma mais simples, trazendo o método ExecuteAsync que deverá conter nossaa lógica, como a seguir.

namespace Lab.HostedService
{
    public class MyBackgroundService
    {
        protected override async Task StartAsync(CancellationToken cancellationToken)
         {
            Console.WriteLine("Host iniciado.");
             return Task.CompletedTask;
         }

        protected override Task StopAsync(CancellationToken cancellationToken)
         {
            Console.WriteLine("Host encerrado.");
            return Task.CompletedTask;
        }

         protected override async Task ExecuteAsync(CancellationToken stoppingToken)
         {
           while(!stoppingToken.IsCancellationRequested)
            {
                //Realiza alguma operação, como tentar ler uma fila ou monitorar uma pasta por novos arquivos
                await Task.Delay(1_000);
            }
         }
    }
}
Enter fullscreen mode Exit fullscreen mode

E assim temos duas formas providas pelo Asp.Net Core para executar operações tão logo nosso host esteja pronto para executá-las, ou em processo de encerramento.

Para maiores informações sobre outras formas de implementar a interface IHostedService, recomendo esta documentação (em inglês).

Espero que tenha gostado! Se gostou, me deixe saber pelos indicadores. Se tiver alguma dúvida, deixe um comentário que responderei assim que puder.

Até a próxima!

Discussion

pic
Editor guide