.NET

23 abr, 2020

Construindo um Windows Service ou Linux Daemon com Worker Service & .NET Core – Parte 1

Publicidade

Fala Galera, Os serviços em background como Windows Service e afins não são nada de novo ou revolucionário em termos de desenvolvimento de software. É bem provável que tenha você já tenha criado alguns serviços ao longo de sua trajetória como Desenvolvedor de Software. Os serviços em background são perfeito para qualquer processamento em segundo plano, como processamento de mensagens de uma fila Kafka, RabbitMQ, SQS, Azure Service Bus e etc, processamento de um arquivo de retorno em caso de compras online com pagamento em boleto entre outros cenários. E para esses cenários em que precisamos criar serviços em background o .NET Core traz um recurso muito interessante: Worker Service. O que é um Worker Service? É um modelo do .NET Core que permite criar serviços em segundo plano (background) para processamentos contínuo ou agendados. Esses serviços em background implementam a interface IHostedService e podem ser implantados como um serviço do Windows, mas também podemos implantar como daemons do Linux. Isso é muito legal =] Neste post, veremos como criar e implantar um Work Service como um Serviço do Windows.

Criando um Work Service

Para criar um Work Service, abra o Visual Studio e selecione Work Service, conforme imagem abaixo: 

O template padrão após a criação do projeto será assim:

public class Program
{
       public static void Main(string[] args)
       {
           CreateHostBuilder(args).Build().Run();
       }
       public static IHostBuilder CreateHostBuilder(string[] args) =>
           Host.CreateDefaultBuilder(args)
               .ConfigureServices((hostContext, services) =>
               {
                   services.AddHostedService<Worker>();
               });
}
public class Worker : BackgroundService
{
        private readonly ILogger<Worker> _logger;
        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
        }
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(1000, stoppingToken);
            }
        }
 }

Como podemos ver, a estrutura é bem básica. Neste serviço ainda não fizemos as sobrecargas (override) dos métodos StartAsync, StopAsync ou Dispose. Caso necessite basta fazer a sobrecarga necessária.

Criando um Work Service como Windows Service

Para que possamos criar um Work Service como Windows Service, devemos utilizar as sobrecargas conforme mencionado acima. Para isso, coloque as sobrecargas conforme código abaixo:

public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
        }
        public override Task StartAsync(CancellationToken cancellationToken)
        {
            return base.StartAsync(cancellationToken);
        }
        public override Task StopAsync(CancellationToken cancellationToken)
        {
            return base.StopAsync(cancellationToken);
        }


        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(1000, stoppingToken);
            }
        }
    }

Fazendo deploy como um Windows Service

Para se fazer um deploy de um Work Service como um Serviço do Windows, precisamos importar um pacote chamado Microsoft.Extensions.Hosting.WindowsServices.  Instale o pacote com o comando: 

install-package Microsoft.Extensions.Hosting.WindowsServices

Feito isso, abra o Program.cs e adicione o método UseWindowsService conforme código abaixo:

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

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseWindowsService()
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                });

    }

Para fazer a instalação do Work Service, vamos utilizar o sc.exe, abra um terminal de comando e execute os passos abaixo:

1 – PUBLICAR COMO UM WORK SERVICE
dotnet publish -o <<PathToPublish>>
 2- FAZER A INSTALAÇÃO
sc.exe create WorkServiceDemo binpath= <<PathBin>>\<<Executavel>>
3 – INICIAR O SERVIÇO
sc.exe start WorkServiceDemo

Caso queira parar o serviço

sc.exe stop WorkServiceDemo

Caso queira excluir o serviço

sc.exe delete WorkServiceDemo

Após fazer o comandos de instalação e iniciar o serviço, você pode verificar o serviço executando no Services do Windows conforme imagem abaixo: 

Conclusão

Quando precisamos executar tarefas em background para processamentos longos, a melhor maneira é criarmos serviços em background para isso. Esses serviços em background são chamados de Work Service no .NET Core. Neste post vimos como criar um Work Service no Windows, no meu próximo post veremos como construir e instalar um daemon no Linux. E ai o que acharam? Comenta aí =] Abs e até a próxima