It is a very common requirement for web applications to be able to run background tasks. Scheduling tasks to run at specific times or intervals, triggering jobs to run based on certain events, etc are common scenarios that we encounter while developing applications. In this article, we are going to learn about Azure WebJobs which provides an excellent way of accomplishing this in a cloud environment.

We’ll start by learning what an Azure WebJob is. Then we’ll look at different types of WebJobs. After that, we’ll learn how to use the Azure WebJobs SDK to create a triggered background job that runs when a new message arrives in the Azure Storage Queue. We’ll test it locally by creating a queue and adding a message. Finally, we’ll deploy it to Azure and test it.

To download the source code for this article, visit the Azure WebJobs repository

To read more about Azure, you can visit our Azure with ASP.NET Core page, where you can find all the articles from the series.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

Let’s start.

Azure WebJobs Introduction

WebJobs is a feature of Azure App Service which we can use to run a program or script from within our Web App, API App, or Mobile App. There are no additional costs for using the WebJobs as it uses the same App Service Plan. Additionally, we can use the Azure WebJobs SDK to simplify many programming tasks with WebJobs. 

Azure Functions provides another way to run programs and scripts in a standalone mode. They are built on top of the Azure Web Jobs foundation and they are the logical successors to WebJobs. We’ll learn about Azure Functions in detail in our Azure Functions article.

The issue with running these kinds of background tasks on the IIS, or any other web server for that matter, is that it consumes the resources that are dedicated to serving the web application. Additionally, these tasks may be interrupted when an app pool recycle occurs. There are, of course, some tricks to push off the app pool recycles until our task has completed, but ideally, we’d like to offload these kinds of tasks outside of the webserver. Azure WebJobs solves this problem. By using a WebJob, we can run a background task without affecting our web application.

Different Types of Azure WebJobs

There are two types of WebJobs:

  • Continuous WebJobs – A continuous WebJob will run continually until someone stops it. When we create this type of WebJob, It starts immediately and keeps on running in the background.
  • Triggered WebJobs – A Triggered WebJob will run only when someone triggers it. They expose a webhook and different services can call it.

A Triggered WebJob is further divided into two types:

  • Scheduled – We can execute a Scheduled WebJob by writing a CRON Expression. CRON Expressions define the schedule on which we need the WebJob to run.
  • Manual – We can of course trigger a WebJob manually by calling the webhook. Several Azure services can communicate with the WebJobs using the webhook triggers. In this article, we are going to implement this type of WebJob using an Azure Storage Queue trigger.   

Azure WebJobs SDK

The Azure WebJobs SDK simplifies the task of creating background jobs that can run in Azure WebJobs. It has a declarative binding syntax that makes it easier to read from and write data into various Azure services. Additionally, it has a trigger system that automatically invokes a function in the WebJob whenever some changes happen in other Azure services. This also provides an integrated Dashboard that we can use to monitor and view diagnostics information about our WebJob runs.

In the next section, we are going to create a .NET Core console application and integrate Azure WebJobs SDK into it. Then, we’ll bind it with an Azure Storage Queue so that whenever a new message arrives in the queue, it triggers our WebJob function.

Integrating a .NET Core Application with Azure WebJobs SDK

First, let’s create a .NET Core Console Application. We can do that by using the Console App (.NET Core) template while creating a new project in Visual Studio:

console app template

Let’s name the project QueueProcessor. 

After that, let’s install the latest stable version of Microsoft.Azure.WebJobs.Extensions NuGet package:

PM> Install-Package Microsoft.Azure.WebJobs.Extensions -version 4.0.1

Cool!

We have created a .NET Core console application that is integrated with the Azure WebJobs SDK.

Configuring the Host

The next step is building a host configuration for our WebJob functions. We need to add the code for that in the Main method inside the Program class:

static async Task Main(string[] args)
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
    });

    var host = builder.Build();

    using (host)
    {
        await host.RunAsync();
    }
}

The ConfigureWebJobs extension method initializes the WebJobs host. While calling the ConfigureWebJobs method, we can initialize specific WebJobs extensions and set properties for those. For instance, we have initialized the Azure Storage Core Services in this example.

Enabling Console Logging

Now we are going to set up the console logging using the ASP.NET Core logging framework.

First, we need to add the Microsoft.Extensions.Logging.Console package:

PM> Install-Package Microsoft.Extensions.Logging.Console -version 3.1.9

Then, we are going to call the ConfigureLogging method inside our Main method:

static async Task Main(string[] args)
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
    });

    builder.ConfigureLogging((context, b) =>
    {
        b.AddConsole();
    });

    var host = builder.Build();
    using (host)
    {
        await host.RunAsync();
    }
}

This adds the console logging capability for our application.

Configuring Storage Binding

The next step is installing the storage binding extension. Let’s start with the  Microsoft.Azure.WebJobs.Extensions.Storage package installation:

PM> Install-Package Microsoft.Azure.WebJobs.Extensions.Storage -version 4.0.3

Then we need to initialize the Storage extension by modifying the call to the ConfigureWebJobs method inside the Main method:

builder.ConfigureWebJobs(b =>
{
    b.AddAzureStorageCoreServices();
    b.AddAzureStorage();
});

Creating a Function

The final step is creating a function that will be triggered when a new message arrives in the Azure Storage Queue. Let’s create a class Functions and add a function called ProcessQueueMessage:  

public static void ProcessQueueMessage([QueueTrigger("webjobqueue")] string message, ILogger logger)
{
    logger.LogInformation(message);
}

The QueueTrigger attribute enables the runtime to call this function when a new message arrives on an Azure Storage Queue called webjobqueue. The queue message is provided to the function as the message parameter. That way, we can process the message data inside the function. In this example, we are just logging the queue message.

Preparing the Azure Storage Account

Now we are going to configure an Azure Storage Account for the demo. For that, first, we need to ensure that we sign in to Visual Studio using an account that has an active Azure subscription. Then we can connect to our Azure subscription in the Server Explorer and it will list out various services:

azure subscription in server explorer

In case the Server Explorer does not automatically connect with our Azure Subscription, we can manually connect by right-clicking on the Azure node and clicking on the Connect to Microsoft Azure Subscription option.

Now we can create an Azure Storage Account by right-clicking on the Storage node and selecting the Create Storage Account option:

create storage account option

Then, we need to provide some information in the Create Storage Account screen: 

create storage account dialog

  1. First, we need to choose a Subscription
  2. Then we need to provide a Name for the storage account
  3. After that, we need to choose a Region
  4. Finally, we need to choose a Replication option. For now, let’s just choose the default option 

After giving these options, we can create the storage account by clicking on the Create button. We’ll learn about different types of Azure Storages and their usages in detail in the Azure Storage article.

Once the storage account is created, we can see that it is listed under the Storage node. We can check the properties by right-clicking on the storage account and clicking on Properties:

storage account property option

On the properties window, we can see the connection string for the storage account:

storage account properties

Clicking the ellipsis towards the right side of the connecting string value will open a dialog with the storage account connection string. Since we’ll require this later, let’s copy the value and keep it somewhere:

storage account connection string

Great!

Our storage account is now ready and we have captured the connection string.   

Testing Azure WebJobs Locally

Now we are going to run the WebJob application locally and test it. While running locally, the WebJobs SDK looks for the storage connection string in the configuration file. So we need to add an appsettings.json configuration file and place the connection string in it:

{
    "AzureWebJobsStorage": "paste the storage connection string value here"
}

Make sure to replace the placeholder with the connection string value that we copied earlier.

After that, we need to change the Copy to Output Directory property of the appsettings.json file to Copy if newer from the Solution Explorer:

appsettings copy to output directory option

This will make sure to copy the appsetting.json file to the output directory when we run the project.

Now let’s build and run the project locally. We can see that the runtime finds our function but does not execute it as there are no triggers yet:

webjob running locally

Now we need to create a storage queue and add a message into it to trigger the function. But before that, we need to stop the project.

Creating the Storage Queue

First, let’s create a queue inside our storage by right-clicking on Queues and selecting the Create Queue option:

create queue option

On the Create Queue dialog, we need to enter the same queue name that we have used as the WebJob function’s QueueTrigger:  

create queue dialog

Once the Queue is created, we can view it by right-clicking and selecting the View Queue option:

view queue option

Of course, the queue will be empty initially. 

Adding Messages to the Queue

We can add a new message into the queue by clicking on the Add Message button:

queue add message option 

Let’s add a message to the queue:

add message to queue

After that, we can see that the message appears in the Queue:

message in queue

Let’s run our WebJob application once again. This time, we can see that the runtime detects a new message in the queue and triggers the function. We can see the details of the execution and the message in the console:

queue message processed by webjob

Cool! 

We have created a queue message and triggered the WebJob function.

Deploying Azure WebJobs

We can deploy a WebJob using Visual Studio in the same way that we deploy an ASP.NET Core application. We have explained the process in detail in our Publishing an ASP.NET Core App to Azure App Service Using Visual Studio article. While deploying a WebJob, we just need to create an app service instance for running it. 

When we choose to publish a .NET Core console app to Azure, it automatically shows the Azure WebJobs option:

publish into azure webjobs option

In the next screen, we can create a new Azure WebJob by clicking the Create a new Azure WebJob link:

select or create webjob option during publish

On the Create a new Azure App Service window, we need to provide some information about the App Service that we are going to create for hosting the WebJob:

create new app service

  1. First, we need to give a Name for the App Service
  2. Then, we need to select an existing Subscription
  3. After that, we need to choose an existing Resource Group or create a new one
  4. Finally, we need to choose an existing Hosting Plan or create a new one

We have explained this step in detail in the Deploying the ASP.NET Core App section of our Publishing an ASP.NET Core App to Azure App Service Using Visual Studio article.

The above step creates an Azure WebJob in the App Service with the details that we have provided. Now we can select the WebJob for publishing and click the Finish button:

publish after creating webjob

Finally, we reach the confirmation screen for publishing and after verifying the details, we can proceed by clicking the Publish button:

confirm publish

This will publish our .NET Core console application into Azure WebJobs.

Testing Azure WebJobs

We can verify that our WebJob is created by navigating to the WebJobs section of the App Service that we just created:

azure webjobs listed inside app service

On selecting the WebJob, we can see the options for running it and viewing the logs. We can run the job by clicking the Run button and then view the logs by clicking on the Logs option:

run option in azure webjobs

Clicking on the Logs button will open the Azure WebJobs Dashboard in a new window. The dashboard will show the WebJob run details.

For testing the Azure WebJob, let’s add another message in the storage queue. We need to make sure that our application is not running locally as it may detect new messages in the queue and process it.

Once we create a new message in the queue, it will trigger the function in Azure WebJob. We can see the detailed logs in the WebJobs dashboard:

azure webjobs dashboard

Cool!

We have verified that the Azure WebJob works fine and is triggered when new messages arrive in the queue.

The architecture that we implemented in this article can be summarized in the below diagram:

azure webjobs architecture

Whenever a new message arrives in the Storage Queue, it triggers the WebJob in the background. The WebJob and Web App reside in the same App Service Plan. Our users can continue using the Web App without knowing the background activities. 

Conclusion

We have learned the following topics in this article:

  • What is an Azure WebJob?
  • Different types of Azure WebJobs.
  • An overview of the Azure WebJobs SDK.
  • Integrating Azure WebJobs SDK into a .NET Core console application.
  • How to trigger a function in WebJob when a new message arrives in Azure Storage Queue 
  • Creating an Azure Storage Queue and adding messages into it.
  • Testing the WebJobs locally.
  • Deploying WebJobs into Azure.
  • Testing the Azure WebJob and inspecting the run details in the dashboard.
Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!