Hoje vamos falar do Hangfire, um framework open-source para gerenciamento de jobs/tasks através de uma aplicação asp.net ou asp.net core, eliminando a necessidade dos serviços do Windows (Windows Service). O Hangfire está disponível em 2 versões, uma chamada apenas de Hangfire e outra de Hangfire Pro. A versão Pro é paga e possui alguns recursos a mais, veja a diferença entre elas clicando aqui. A versão free atende a grande maioria dos casos, tem seu código disponível no GitHub, e é dela que vamos falar hoje.
Com o Hangfire você pode criar jobs recorrentes, que executam apenas uma vez (fire and forget) ou com uma data agendada (delayed). E vamos ver como criar cada um deles, para isso, vamos começar criando uma aplicação web nova. Você pode rodar o Hangfire em qualquer tipo de aplicação asp.net ou asp.net core. Além disso, o Hangfire possui um dashboard bem bacana que contém informações dos jobs.
Para controlar a execução dos jobs, o Hangfire utiliza um banco de dados para isso, que por padrão é o MS Sql Server da Microsoft, e para a versão Pro existe a opção de utilização do Redis. Existem outras opções disponíveis para a versão gratuita, como MySql, PostgreSql e o MongoDB. A lista completa de bancos suportados você encontra aqui.
Eu vou fazer em cima de uma aplicação asp.net core com um banco de dados MS Sql Server. Abra o Visual Studio 2017, e crie uma aplicação do tipo ASP.NET Core Web Application (.NET Core) com o nome WebDemoHangfire e na tela seguinte selecione o template Web API. Após criar o projeto, vamos adicionar o Hangfire ao nosso projeto, para isso abra o console do Nuget e digite:
Install-Package HangFire
Agora nós precisamos alterar nossa classe Startup para que nossa aplicação carregue o Hangfire quando iniciar. Adicione a linha abaixo ao método ConfigureServices:
services.AddHangfire(x => x.UseSqlServerStorage("Data Source=localhost;Initial Catalog=hangfire;User id=hangfire;Password=hangfire;"));
Dessa forma o método completo ficará assim:
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddHangfire(x => x.UseSqlServerStorage("Data Source=localhost;Initial Catalog=hangfire;User id=hangfire;Password=hangfire;")); services.AddMvc(); }
E também precisamos alterar o método Configure, adicionando as linhas abaixo:
app.UseHangfireServer(); app.UseHangfireDashboard();
Deixando o método completo dessa forma:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app.UseHangfireServer(); app.UseHangfireDashboard(); app.UseMvc(); }
Se você rodar a aplicação agora, verá que foram criadas algumas tabelas no SqlServer, e ao abrir o endereço abaixo, você deve ver o dashboard:
http://localhost:54782/hangfire
Não esqueça de trocar a porta para a utilizada pela sua aplicação. Agora vamos ver como fazemos para criar cada um dos tipos de job disponíveis no Hangfire, e para começar vamos ver como criar um job que executa apenas uma vez, na hora em que é criado:
var jobFireForget = BackgroundJob.Enqueue(() => Debug.WriteLine($"Fire and forget: {DateTime.Now}"));
Para criar um job do tipo fire and forget, utilizamos o método Enqueue da classe BackgroundJob. Em nosso exemplo quando o job for executado ele irá imprimir no console o texto “Fire and Forget” acompanhado da data de execução.
Agora vamos criar um job do tipo delayed, para isso utilizamos o método Schedule, também disponível na classe BackgroundJob, que tem como um dos parâmetros o momento que o job deve ser executado, ou em quanto tempo após sua criação deve ser executado, e em nosso exemplo foi configurado para rodar após 30 segundos:
var jobDelayed = BackgroundJob.Schedule(() => Debug.WriteLine($"Delayed: {DateTime.Now}"), TimeSpan.FromSeconds(30));
O Hangfire também permite criarmos jobs que executam após o término de algum outro job, e para criá-los nós utilizamos o método ContinueWith da classe BackgroundJob, sendo que um dos parâmetros que devem ser informados é qual o job o término deve ser aguardado:
BackgroundJob.ContinueWith(jobDelayed, () => Debug.WriteLine($"Continuation: {DateTime.Now}"));
E por fim, vamos ver como criar jobs que executam periodicamente, para isso utilizamos a classe RecurringJob e o método AddOrUpdate, que tem como um dos parâmetros o tempo que o job deve esperar para cada execução:
RecurringJob.AddOrUpdate(() => Debug.WriteLine($"Recurring: {DateTime.Now}"), Cron.Minutely);
Agora que vimos como criar alguns jobs de exemplo, vamos criar um controller com o nome JobsController, e nele vamos colocar um método GET, que irá criar todos os nossos jobs. Então, crie o método abaixo:
[HttpGet] public string Get() { Console.WriteLine($"Request: {DateTime.Now}"); var jobFireForget = BackgroundJob.Enqueue(() => Debug.WriteLine($"Fire and forget: {DateTime.Now}")); var jobDelayed = BackgroundJob.Schedule(() => Debug.WriteLine($"Delayed: {DateTime.Now}"), TimeSpan.FromSeconds(30)); BackgroundJob.ContinueWith(jobDelayed, () => Debug.WriteLine($"Continuation: {DateTime.Now}")); RecurringJob.AddOrUpdate(() => Debug.WriteLine($"Recurring: {DateTime.Now}"), Cron.Minutely); return "Jobs criados com sucesso!"; }
Agora, execute nossa aplicação e abra o endereço abaixo:
http://localhost:54782/api/jobs
E veja o resultado das execuções impressas no console, com uma descrição do tipo do job e a data de execução. Além disso, se você fizer um select na tabela JOB você verá todo histórico de execução de cada um dos jobs. Não se esqueça de abrir o dashboard do Hangfire para acompanhar as execuções dos jobs:
http://localhost:54782/hangfire
O Hangfire também pode ser utilizado em conjunto com um container de injeção de dependência, como o Autofac, e nós vamos mostrar como aqui em um próximo post, fique ligado. E como é costume aqui em nosso blog, o código-fonte completo do nosso exemplo está disponível no GitHub: https://github.com/desenvolvedorninja/hangfire-primeiros-passos.

Quase 20 anos de experiência no mercado de TI.
Atuação em grandes empresas como Netshoes, Borland, JBS, Bradesco, Hospital das Clínicas, Rede, Prodam, HSPE, Instituto Ayrton Senna, e também em empresas internacionais como Delta Dental, T-Mobile, Pepsi e Mckesson.
Fundador da TecPrime Solutions, administrador da comunidade nopCommerce Brasil, e autor dos sites InvestFacil.net e Desenvolvedores.ninja
Muito bacana o post, obrigado pelo conteúdo !
Acho que vou precisar usar ele, então aqui já tenho uma boa referência, obrigado.