The background task is a type of task which runs in the background. For example, sometimes we run any task and it takes a long time so start a new task to work more efficiently. Let's take the example in the coding world sometimes we have to log in one page and after a fewprocesses need to send an email to the client so we can do send mail process in the background and continue the process which is unfinished in this sending mail is Background task.
Why we need background Tasks?
The background task is important when you need to run an operation which is taking a long time to finish its operations. Without the background task, we need to perform both operations one by one and the response can also take more time to reach the user and it is a bad user experience. With the Background task, you can run the task in the background to complete and give a response to the user more quickly and it is a good user experience.
What is Hangfire?
Hangfire is an open-source framework. It helps in creating a new process and manage the Background Task. The background task is also called The Background job. Hangfire help us to manage background tasks for example some tasks you can't put in the processing pipeline. From that type of operations some are listed below:
-
mass notifications/newsletter
-
batch import from xml, csv, json
-
creation of archives
-
firing off web hooks
-
deleting users
-
building different graphs
-
image/video processing
-
purge temporary files
-
recurring automated reports
-
database maintenance
Type of Hangfire Jobs
Hangfire had so many types of jobs a few of them are listed below:
-
Fire-and-forget
-
Delayed
-
Recurring
-
Continuations of other jobs
The Background Jobs are stored in your selected place. Hangfire has supported so many storages that are based on documents and relational.
Hangfire has its own automatic retry logic that retries the jobs and completes them so don't worry about the error thrown by the jobs. It uses workers to handle the tasks, you define the number of workers you would like and that they share the queue, running the tasks on a primary-come first-serve basis. Hang fire’s UI is itself protected by an API key and accessible from /Hangfire if you have the API key.
Now let's know how to configure Hangfire:
First of all, you need to create your regular core project. and have to select .NET5 in the web application.
After creating the project to use Hangfire, install a NuGet package of Hangfire is required. Below are listed some packages of Hangfire which are helpful to configure and setup authentication and store job-related information in SQL.
-Hangfire.AspNetCore
- Hangfire.Dashboard.Basic.Authentication
-Hangfire.MemoryStorage
-Hangfire.SqlServer
In this program, we will create connectivity with the database using DbFirst.So need to create one model first:
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; namespace HangfireDemo.Model { public class EmployeeData { [Key] public int Id { get; set; } public string EmployeeName { get; set; } public string DesignationName { get; set; } } }
After creating model create DBContex in AppDbContext give its name EmpContex.cs like below:
using Hangfire.Model; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Hangfire.AppDbContext { public partial class EmpContex : DbContext { public EmpContex(DbContextOptions options) : base(options) { } public DbSetEmployees { get; set; } } }
After setting up the Connection string in appsettings.js, change code like below in Startup.cs file:
using Hangfire.AppDbContext; using Hangfire.Services; using HangfireBasicAuthenticationFilter; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.OpenApi.Models; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace DemoHangfire { public class Startup { private static IEmpService EmpService; private readonly Job taskscheduler= new Job(EmpService); public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method is called at the runtime. Use this method to add services in container. public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Hangfire", Version = "v1" }); }); #region set Connection String services.AddDbContext(item => item.UseSqlServer(Configuration.GetConnectionString("myconn"))); #endregion #region Configure Hangfire services.AddHangfire(c => c.UseSqlServerStorage(Configuration.GetConnectionString("myconn"))); GlobalConfiguration.Configuration.UseSqlServerStorage(Configuration.GetConnectionString("myconn")).WithJobExpirationTimeout(TimeSpan.FromDays(7)); #endregion #region Services Injection services.AddTransient (); #endregion } // This method called at the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env,IBackgroundJobClient backgroundJobClient, IRecurringJobManager recurringJobManager) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Hangfire v1")); } #region Configure Hangfire app.UseHangfireServer(); //Basic Authentication added to access the Hangfire Dashboard app.UseHangfireDashboard("/hangfire", new DashboardOptions() { AppPath = null, DashboardTitle = "Hangfire Dashboard", Authorization = new[]{ new HangfireCustomBasicAuthenticationFilter{ User = Configuration.GetSection("HangfireCredentials:UserName").Value, Pass = Configuration.GetSection("HangfireCredentials:Password").Value } }, //Authorization = new[] { new DashboardNoAuthorizationFilter() }, //IgnoreAntiforgeryToken = true }); ; #endregion app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); #region Job Scheduling Tasks //recurringJobManager.AddOrUpdate("Insert Employee : Runs Every 1 Min", () => jobscheduler.JobAsync(), "*/1 * * * *"); #endregion } } }
Looking to Hire .Net Developer? Your Search ends here.
Now create database table using the Migration commands and after create services for that.
EmpService.cs using Hangfire.AppDbContext; using Hangfire.Model; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Hangfire.Services { public class EmployeeService : IEmployeeService { private readonly EmployeeDbContext _employeeDbContext; public EmployeeService(EmployeeDbContext employeeDbContext) { _employeeDbContext = employeeDbContext; } public async TaskStarup.csInsertEmployeeAsync() { try { Employee employee = new Employee() { EmployeeName = "Jk", Designation = "Full Stack Developer" }; await _employeeDbContext.AddAsync(employee); await _employeeDbContext.SaveChangesAsync(); return true; } catch (Exception ex) { throw; } } } } IEmpService.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Hangfire.Services { public interface IEmpService { Task InsertEmployeeAsync(); } } We are complete service injection in privious step in Startup.cs file #region Services Injection services.AddTransient (); #endregion Now set the Password and id for access the Hangfire Dashboard appsettings.js "HangfireCredentials": { "UserName": "Demo", "Password": "Demo@123" }
//add Authentication to access the Hangfire Dashboard app.UseHangfireDashboard("/hangfire", new DashboardOptions() { AppPath = null, DashboardTitle = "Hangfire Dashboard", Authorization = new[]{ new HangfireCustomBasicAuthenticationFilter{ User = Configuration.GetSection("HangfireCredentials:UserName").Value, Pass = Configuration.GetSection("HangfireCredentials:Password").Value } }, }); ;
Create background tasks
BJob.cs
using Hangfire.Services; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace DemoHangfire { public class BJob { #region Property private readonly EmpService _EmpService; #endregion #region Constructor public Job(IEmployeeService employeeService) { _EmpService = EmpService } #endregion #region Job Scheduler public async TaskJobAsync() { var result = await __EmpService.InsertEmployeeAsync(); return true; } #endregion } }
After completingthe above process add Background task in Startup.cs
#region Job Scheduling Tasks // Recurring Job for every 5 min recurringJobManager.AddOrUpdate("Insert Employee : Runs Every 1 Min", () => jobscheduler.JobAsync(), "*/5 * * * *"); //Fire and forget job var jobId = backgroundJobClient.Enqueue(() => jobscheduler.JobAsync()); //Continous the Job backgroundJobClient.ContinueJobWith(jobId, () => jobscheduler.JobAsync()); //Schedule Job backgroundJobClient.Schedule(() => jobscheduler.JobAsync(), TimeSpan.FromDays(5)); #endregion
After completing, the whole process for configuring the Hangfire, create the background jobs now run the project in the browser you can initially see the Swagger page. Remove swagger and write Hangfire and see the Hangfire view.
Conclusion
After reading this blog you will surely understand about the Hangfire and background jobs. Also, will come to know about the background process and how it is important for creating a more efficient web application. We also explained that how to configure Hangfire in the project and how to run it.
Make your background task easy with Hangfire in .NET The background task is a type of task which runs in the background. For example, sometimes we run any task and it takes a long time so start a new task to work more efficiently. Let's take the example in the coding world sometimes we have to log in one page and after a fewprocesses need to send an email to the client so we can do send mail process in the background and continue the process which is unfinished in this sending mail is Background task. Why we need background Tasks? The background task is important when you need to run an operation which is taking a long time to finish its operations. Without the background task, we need to perform both operations one by one and the response can also take more time to reach the user and it is a bad user experience. With the Background task, you can run the task in the background to complete and give a response to the user more quickly and it is a good user experience. What is Hangfire? Hangfire is an open-source framework. It helps in creating a new process and manage the Background Task. The background task is also called The Background job. Hangfire help us to manage background tasks for example some tasks you can't put in the processing pipeline. From that type of operations some are listed below: mass notifications/newsletter batch import from xml, csv, json creation of archives firing off web hooks deleting users building different graphs image/video processing purge temporary files recurring automated reports database maintenance Type of Hangfire Jobs Hangfire had so many types of jobs a few of them are listed below: Fire-and-forget Delayed Recurring Continuations of other jobs The Background Jobs are stored in your selected place. Hangfire has supported so many storages that are based on documents and relational. Hangfire has its own automatic retry logic that retries the jobs and completes them so don't worry about the error thrown by the jobs. It uses workers to handle the tasks, you define the number of workers you would like and that they share the queue, running the tasks on a primary-come first-serve basis. Hang fire’s UI is itself protected by an API key and accessible from /Hangfire if you have the API key. Now let's know how to configure Hangfire: First of all, you need to create your regular core project. and have to select .NET5 in the web application. After creating the project to use Hangfire, install a NuGet package of Hangfire is required. Below are listed some packages of Hangfire which are helpful to configure and setup authentication and store job-related information in SQL. -Hangfire.AspNetCore - Hangfire.Dashboard.Basic.Authentication -Hangfire.MemoryStorage -Hangfire.SqlServer Read More: Basic Authentication In Swagger (Open Api) .net5 In this program, we will create connectivity with the database using DbFirst.So need to create one model first: using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; namespace HangfireDemo.Model { public class EmployeeData { [Key] public int Id { get; set; } public string EmployeeName { get; set; } public string DesignationName { get; set; } } } After creating model create DBContex in AppDbContext give its name EmpContex.cs like below: using Hangfire.Model; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Hangfire.AppDbContext { public partial class EmpContex : DbContext { public EmpContex(DbContextOptions options) : base(options) { } public DbSet Employees { get; set; } } } After setting up the Connection string in appsettings.js, change code like below in Startup.cs file: using Hangfire.AppDbContext; using Hangfire.Services; using HangfireBasicAuthenticationFilter; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.OpenApi.Models; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace DemoHangfire { public class Startup { private static IEmpService EmpService; private readonly Job taskscheduler= new Job(EmpService); public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method is called at the runtime. Use this method to add services in container. public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Hangfire", Version = "v1" }); }); #region set Connection String services.AddDbContext(item => item.UseSqlServer(Configuration.GetConnectionString("myconn"))); #endregion #region Configure Hangfire services.AddHangfire(c => c.UseSqlServerStorage(Configuration.GetConnectionString("myconn"))); GlobalConfiguration.Configuration.UseSqlServerStorage(Configuration.GetConnectionString("myconn")).WithJobExpirationTimeout(TimeSpan.FromDays(7)); #endregion #region Services Injection services.AddTransient(); #endregion } // This method called at the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env,IBackgroundJobClient backgroundJobClient, IRecurringJobManager recurringJobManager) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Hangfire v1")); } #region Configure Hangfire app.UseHangfireServer(); //Basic Authentication added to access the Hangfire Dashboard app.UseHangfireDashboard("/hangfire", new DashboardOptions() { AppPath = null, DashboardTitle = "Hangfire Dashboard", Authorization = new[]{ new HangfireCustomBasicAuthenticationFilter{ User = Configuration.GetSection("HangfireCredentials:UserName").Value, Pass = Configuration.GetSection("HangfireCredentials:Password").Value } }, //Authorization = new[] { new DashboardNoAuthorizationFilter() }, //IgnoreAntiforgeryToken = true }); ; #endregion app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); #region Job Scheduling Tasks //recurringJobManager.AddOrUpdate("Insert Employee : Runs Every 1 Min", () => jobscheduler.JobAsync(), "*/1 * * * *"); #endregion } } } Looking to Hire .Net Developer? Your Search ends here. See here Now create database table using the Migration commands and after create services for that. EmpService.cs using Hangfire.AppDbContext; using Hangfire.Model; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Hangfire.Services { public class EmployeeService : IEmployeeService { private readonly EmployeeDbContext _employeeDbContext; public EmployeeService(EmployeeDbContext employeeDbContext) { _employeeDbContext = employeeDbContext; } public async Task InsertEmployeeAsync() { try { Employee employee = new Employee() { EmployeeName = "Jk", Designation = "Full Stack Developer" }; await _employeeDbContext.AddAsync(employee); await _employeeDbContext.SaveChangesAsync(); return true; } catch (Exception ex) { throw; } } } } IEmpService.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Hangfire.Services { public interface IEmpService { Task InsertEmployeeAsync(); } } We are complete service injection in privious step in Startup.cs file #region Services Injection services.AddTransient(); #endregion Now set the Password and id for access the Hangfire Dashboard appsettings.js "HangfireCredentials": { "UserName": "Demo", "Password": "Demo@123" } Starup.cs //add Authentication to access the Hangfire Dashboard app.UseHangfireDashboard("/hangfire", new DashboardOptions() { AppPath = null, DashboardTitle = "Hangfire Dashboard", Authorization = new[]{ new HangfireCustomBasicAuthenticationFilter{ User = Configuration.GetSection("HangfireCredentials:UserName").Value, Pass = Configuration.GetSection("HangfireCredentials:Password").Value } }, }); ; Create background tasks BJob.cs using Hangfire.Services; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace DemoHangfire { public class BJob { #region Property private readonly EmpService _EmpService; #endregion #region Constructor public Job(IEmployeeService employeeService) { _EmpService = EmpService } #endregion #region Job Scheduler public async Task JobAsync() { var result = await __EmpService.InsertEmployeeAsync(); return true; } #endregion } } After completingthe above process add Background task in Startup.cs #region Job Scheduling Tasks // Recurring Job for every 5 min recurringJobManager.AddOrUpdate("Insert Employee : Runs Every 1 Min", () => jobscheduler.JobAsync(), "*/5 * * * *"); //Fire and forget job var jobId = backgroundJobClient.Enqueue(() => jobscheduler.JobAsync()); //Continous the Job backgroundJobClient.ContinueJobWith(jobId, () => jobscheduler.JobAsync()); //Schedule Job backgroundJobClient.Schedule(() => jobscheduler.JobAsync(), TimeSpan.FromDays(5)); #endregion After completing, the whole process for configuring the Hangfire, create the background jobs now run the project in the browser you can initially see the Swagger page. Remove swagger and write Hangfire and see the Hangfire view. Conclusion After reading this blog you will surely understand about the Hangfire and background jobs. Also, will come to know about the background process and how it is important for creating a more efficient web application. We also explained that how to configure Hangfire in the project and how to run it.
Build Your Agile Team