Offloading tasks to run in the background can be really useful. There are times when your users don’t need to wait around for a task  (such as sending an email) to finish

One thing that’s always bothered me though is the ceremony involved in consuming messages. Whether it’s RabbitMQ or Amazon SQS I’ve had to write some variation of a while(true) loop to keep checking the queue for any new messages.

Azure Web Jobs can really simplify your message consuming code and finally get rid of those pesky loops!

Storage queues

I opted to use storage queues instead of service bus as webjobs uses them “out of the box” and they’re easy to get started with.

public void SubmitDetails(string fromEmail, string fromName, string message)
{
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=accountName;AccountKey=someKey");
    CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();

    CloudQueue queue = queueClient.GetQueueReference("contact-us");
    queue.CreateIfNotExists();

    var contactUsMessage = new ContactUsMessage(fromEmail, fromName, message);
    queue.AddMessage(new CloudQueueMessage(JsonConvert.SerializeObject(contactUsMessage)));
}

This code is simple enough. I need a queue so this code creates one (if it doesn’t already exist) then pushes a message onto it.

Webjobs work so you don’t have to

The real fun starts when we consume these messages using webjobs.

There’s a webjobs project template available in Visual Studio which adds a webjobs project to any existing solution. Keeping the webjobs project with your web site makes it easy to manage.

Add Web Jobs

class Program
{
    // Please set the following connection strings in app.config for this WebJob to run:
    // AzureWebJobsDashboard and AzureWebJobsStorage
    static void Main()
    {
        var host = new JobHost();
        // The following code ensures that the WebJob will be running continuously
        host.RunAndBlock();
    }
}

This boilerplate code in program.cs tells us what to do next.

I already had a storage account set up in Azure (I used it earlier when sending messages) so I set that in app.config for both AzureWebJobsDashboard and AzureWebJobsStorage.

configure webjobs

A word to the wise, you can’t use the development storage (emulator) for webjobs so don’t even try (I found out the hard way when my first attempt blew up).

With the connection sorted I turned to receiving messages when they’re pushed onto the queue.

public class Functions
{
    // This function will get triggered/executed when a new message is written 
    // on an Azure Queue called queue.
    public static void ProcessQueueMessage([QueueTrigger("contact-us")] ContactUsMessage message, TextWriter log)
    {
        EmailSender.Send(message.FromEmail, message.FromName, message.Message);
    }
}

This is brilliant. I love the fact that the message is automatically deserialised. It’s easy to test too because the webjobs.exe can run locally as well as being deployed to the cloud.

webjobs running

So how do you deploy this thing to Azure?

Publish web job

At first I was concerned that publishing to an existing web site on Azure might overwrite the site with the WebJob but using the Publish as Azure WebJob menu option in Visual Studio deploys it alongside your web app.

Making it visible

When you view the app in the Azure Portal there is a link to view the WebJob and it’s dashboard.

WebJobs in Azure Portal

My first attempt to view the dashboard didn’t go so well when I got this error.

“Make sure that you are setting a connection string named AzureWebJobsDashboard in your Microsoft Azure Website configuration by using the following formatDefaultEndpointsProtocol=https;AccountName=NAME;AccountKey=KEY pointing to the Microsoft Azure Storage account where the Microsoft Azure WebJobs Runtime logs are stored.”

webjobs error

For some reason Microsoft feel the need to tell you this twice.

This is easy to correct, you just need to set your storage connection strings for your web app in the portal (via settings).

webjobs connection strings

And that’s that. You might have noticed that I actually have two web job instances up and running for this web app. If you’re thinking about smaller, more focused services (microservices) this is useful as you can split up your background tasks into their own webjobs. Just add more webjobs project to your solution.

Turning it up to eleven

There’s a lot more that can be done with Azure Web Jobs, not least running scheduled tasks and using Service Bus to perform multiple actions from the same message.

Finally I’d love to hear from you,  what do you want to know about web jobs, If you’ve used them what challenges have you faced?

 

 

 

 

Want to learn .net Core?

  • Want to learn .NET Core but don't know where to start?
  • Don't have time to keep up with everything Microsoft is putting out?
  • Stuck on legacy apps when you want to build something new?
Enter your details below and get my weekly update; learn how to build better .NET web apps.
comments powered by Disqus