Using Hangfire to Run Background Jobs in IIS
Recently one of our clients went through an application modernization project to upgrade and update their internal business applications. Among the technical challenges to conquer was how to handle long-running and recurring scheduled jobs. In the existing system, the long-running jobs were being allowed to run in process, with the users being instructed to initiate the process in their browsers and then not do anything until it finished. An obvious issue with this was that timeouts were possible, and of course, the user could not perform any other actions in the application until the long-running process was done. Meanwhile, the scheduled jobs were run through a console application installed on the server and triggered using a Windows Scheduled Task. This process worked well enough for what it is, but also provided no real visibility or error handling and no way to resume or retry failed jobs.
Using Hangfire to handle scheduled jobs
The solution we chose to address these problems was to adopt the use of Hangfire. This excellent open-source solution provided just the ticket to handle background and scheduled jobs and was incredibly easy to integrate into our customer’s applications. Hangfire is very well documented. The Open subscription is sufficient for many workflows, but more advanced subscriptions are available to solve more complicated problems and support additional storage choices other than SQL Server. So how does it work? Hangfire uses a persistent queue (in our case stored in SQL Server) to store jobs, which are acted upon by Hangfire worker threads that run within their own execution context instead of running synchronously in the web application. This frees up the user to fire and forget jobs and continues working on other things while they wait for them to finish. The same worker pool also picks up and executes scheduled recurring jobs.
Configuring the application to use Hangfire is simple. After adding the NuGet packages to the solution we just had to configure our Startup.cs to set up the Hangfire server and dashboard. Below is the code from ConfigureServices() – with all the non-Hangfire bits removed.
The settings above are mostly the recommended defaults. The QueuePollInterval controls the immediacy of when Hangfire invokes a new job when it is added to the queue. We chose one minute instead of the default 0 (right away). Likewise, we opted to reduce the number of workers available to be only twice the number of processors on the server so as not to overstress the webserver.
Notice the Hangfire database connection. To set up Hangfire’s SQL Server backend you simply need to create an empty database and specify that database in your UseSqlServerStorage configuration. The first time the application starts in IIS it will trigger creating the entire database schema needed to support Hangfire. One gotcha, make sure your database user has DDL_Admin permissions or this step will error.
What else do you need to do? Hangfire comes with a fantastic built-in monitoring user interface, the Hangfire dashboard. And again, it’s easy to set up.
At the root of your application, you can now add the /hangfire to your URL and every aspect of the Hangfire dashboard is there at your fingertips. If you don’t want anyone and everyone to view this, just do as we have done above and add an authorization filter. In our case, the filter uses RBAC to check that the user has an application admin role. We’ve also reduced the polling interval. Our users don’t access this dashboard that frequently and they don’t require continuous updates.
And that’s it for setup. All we need to do now is define some scheduled jobs. You guessed it; this too is easy. Here’s an example:
This code will cause Hangfire’s recurring job manager to execute the specified function according to the Cron schedule provided, in this case, every 30 minutes. Progress, success, and failure will all be captured in the database and viewable in the dashboard.
Want to add a fire-and-forget job to the queue instead? No problem. Just add the job to the background queue. Here’s an example:
Hangfire has served us well and we highly recommend it. The source documentation details many other ways in which Hangfire can be configured and used, so refer to that at the link above. At the time of writing, we have successfully run thousands of jobs in production, with few failures (none of them due to Hangfire itself).
Thank you for reading this post! If you enjoyed it, please check out some of our other content on this blog. We have a range of articles on various topics that I think you’ll find interesting. Also, don’t forget to subscribe to our newsletter to stay updated with our recent successful application development projects.
Customized Modern Search Experiences with PnP Search Web Parts November 23, 2023 Today, PnP Search is often used in SharePoint to create customized search pages and result displays. This results…
The Imaginet Difference: An Exclusive Look at Imaginet’s Onboarding Process November 16, 2023 Most new developers are familiar with the dread of “onboarding.” Onboarding refers to the first few weeks…
Let’s Build Something Amazing Together
From concept to handoff, we’d love to learn more about what you are working on. Send us a message below or call us at 1-800-989-6022.