.NET Core – Running Background Worker on IIS

One of the crucial pieces of the new solution that I’m working on is RabbitMQ. For those who have never heard of RabbitMQ, it is one of the most widely used open source message broker. Since our solution is hosted on-premise, RabbitMQ was one of the most natural fit for us. Our entire solution architecture is built on .NET Core 2.1 and recently migrated to .NET Core 2.2. To run the RabbitMQ we had 3 options:

  • Run RabbitMQ as a traditional .NET Framework “Windows Service”
  • Run RabbitMQ as a .NET Core “Windows Service”
  • Host RabbitMQ on IIS as a .NET Core application

Creating a .NET Framework based Windows Service was a known beast, as we have done it hundred times. However, since our entire solution was based on .NET Core, it was a step backward. As a result, we started exploring option 2, that is running RabbitMQ as a .NET Core based Windows Service. Our solution was largely inspired (read “Copied”) from Steve Gordan’s post on “Running a .NET Core Generic Host App as a Windows Service

Based on his post, we configured the solution to run as console application during development, and then as windows service at the time of deployment. However, we did not find deploying the windows service on .NET Core as simple as we initially thought. We had to modify project file to add RunTimeIdentifier or RID. RID is OS and architecture specific. It is a different string based on OS, Version, Architecture. We did not want OS specific dependencies in our solution. In addition to this, a Windows-service also come up with its own set of complexities. It is difficult to debug and monitor as compared to a web hosted-service.

This is where we looked into the third option: Host the Background Worker on IIS. Hosting the Background Worker on IIS meant that we were able to deploy our Background Worker same as we would deploy a web app. Instead of using a “Generic Host” we were able to use default “Web Host”. There was less custom code. It was easier to debug and monitor. In addition to this, we were also able to leverage .NET Core Health Checks.

To run the background worker on the IIS, we had to tweak IIS settings to keep it always up and running. Here is the PowerShell script which we run on Octopus to update the IIS settings.

## IIS WebAdmin Module
Import-Module WebAdministration
$AppPoolInstance = Get-Item IIS:\AppPools\$AppPool
Write-Output "Set Site PreLoadEnabled to true"
Set-ItemProperty IIS:\Sites\$Site -name applicationDefaults.preloadEnabled -value True
Write-Output "Set Recycling.periodicRestart.time = 0"
$AppPoolInstance.Recycling.periodicRestart.time = [TimeSpan]::Parse("0");
$AppPoolInstance | Set-Item
Write-Output "Set App Pool start up mode to AlwaysRunning"
$AppPoolInstance.startMode = "alwaysrunning"
Write-Output "Disable App Pool Idle Timeout"
$AppPoolInstance.processModel.idleTimeout = [TimeSpan]::FromMinutes(0)
$AppPoolInstance | Set-Item
if ($appPoolStatus -ne "Started") {
Write-Output "Starting App Pool"
Start-WebAppPool $AppPool
} else {
Write-Output "Restarting App Pool"
Restart-WebAppPool $AppPool
view raw AlwaysOn.ps hosted with ❤ by GitHub

Hope you find this useful. 🙂