With Visual Studio Update 3, the Web Tools Extensions team added a number of great features to make it easier for ASP.NET developers publishing web applications to Azure Websites to enable background processing using Azure WebJobs. Since the Update 3 release, Azure WebJobs has reached general availability, and to coincide with the release of Azure WebJobs we’ve added more features to Visual Studio to make it easier than ever to build, deploy, and debug WebJobs. This blog post will introduce you to some of the new features for developers who want to create, deploy, and debug Azure WebJobs. Through a simple walk-through of getting an ASP.NET site enabled with a pair of Azure WebJobs, you’ll learn how to get started without even leaving Visual Studio.
Adding WebJobs to an Existing ASP.NET Web App
To start this demonstration, I’ve created a bare-bones ASP.NET MVC Web Site using Visual Studio 2013. WebJobs can be added to any existing ASP.NET application. Likewise, the Azure SDK includes project templates for creating WebJobs without the need for an existing ASP.NET application. WebJobs can be deployed either as part of an existing ASP.NET web project, or they can be deployed to Azure Websites directly via a simple project-level context menu item.
I’ll right-click the Web Application Project node in Solution Explorer, expand the Add context menu, and select the New Azure WebJob Project context menu item from the fly-out. This will drop a new Azure WebJob project into my existing Visual Studio solution. If I’d had an existing Console Application or WebJobs project sitting on disk, I could have selected the Existing Project as Azure WebJob context menu instead, which would allow me to browse my local computer to find an existing project.
When I select the New Azure WebJob Project context menu item, the Add Azure WebJob dialog opens. Using this dialog, I’ll specify that I want this first WebJob to be a Continuous one. I’ll give the Project and WebJob a name, and click the OK button.
With Visual Studio Update 4 or the Azure SDK 2.5, I’ll have two project templates to choose from based on the run mode of my WebJob. Since I’ve selected Continuous for this first WebJob, the code dropped into the project will be specific to a continuous scenario.
Once the project is added to my solution, I’ll open up the Program.cs file from the project. The code in this file uses the WebJobs’ JobHost object to start up the WebJob and block it from exiting. This will allow the continuous WebJob to remain in memory so that it can monitor an Azure Storage Queue for incoming messages.
Included along with the Program.cs file that launches my WebJob is a second file containing boilerplate code that uses the WebJobs SDK to watch an Azure Storage Queue. The code below, from Functions.cs, demonstrates how the QueueTrigger attribute is used to define a method parameter as one that will be populated when messages land on the Storage Queue being watched by the code. For more information on the various attributes available for monitoring Queues, Blobs, or Service Bus objects, take a look at the long list of WebJobs SDK resources available on ASP.NET.
I’ll follow the same process again to add a second WebJob to the ASP.NET project. This time I’ll select Run on Demand from the Run Type menu. This WebJob will be one that doesn’t run continuously or watch Azure Storage Queues, but rather, will run only when a user elects to run the WebJob from within Visual Studio or from the Azure Management Portal.
The code for scheduled and on-demand WebJobs is slightly different from the code dropped in for continuous WebJobs. The Program.cs code for an on-demand job, shown below, doesn’t block the WebJob’s EXE from exiting. Instead, it presumes a one-time run is needed, and then the WebJob simply exits.
The code below, from the on-demand WebJob project, simply has a method in it named ManualTrigger that drops a message into an Azure Storage Queue using the Queue attribute decorating the final method parameter. When the value of this out parameter is set in the second line of the method, a new Azure Storage Queue message is dropped into the queue so that it can be processed by the first WebJob, which is running continuously and watching the queue for incoming messages.
The idea is simple – the first WebJob is running continuously, watching an Azure Storage Queue for incoming messages, whereas the second WebJob will be executed manually to drop messages into the Azure Storage Queue being watched.
Simultaneous Web Site and WebJob Publishing from Visual Studio
Now that the site is ready and armed with both on-demand and continuous WebJobs for background processing, the site and the WebJobs can easily be published with one context-menu click. The WebJobs tooling knows, at this point, that the two WebJob projects should be published along with the Web Application Project’s content files.
Since I’ll be publishing my Web Application with WebJobs, I’ll need to select Microsoft Azure Websites when asked what my publishing target will be.
Since I don’t yet have a destination Website running in Azure to which my Web Application Project can be deployed, I’ll click the New button in the Select Existing Website dialog.
I’ll give the site a name and select the appropriate region for it to be published into.
To enable remote debugging of my Website and Azure WebJobs, I’ll select Debug from the Configuration drop-down menu.
During the publish preview, take note that the WebJobs are going to be published along with the Website contents. Since WebJobs run from the App_Data folder of an existing Website, I can see the two WebJobs’ content in the Publish Preview dialog.
Azure WebJobs make use of Azure Storage for passing messages through queues and for storing or retrieving files from Azure Blob containers. In addition, the WebJobs Dashboard makes use of Azure Storage to store up statistics about how and when the WebJobs are executed. To reap these benefits, I’ll need to configure the host Azure Website with the Storage Account connection string for my WebJobs storage and dashboard.
Configuring the WebJobs Connection String
Luckily, the Azure SDK for Visual Studio gives me easy accessibility to my Azure Storage accounts within the Visual Studio Server Explorer. By right-clicking on the Storage node of the Server Explorer, I can easily create a new Azure Storage Account using the context menu.
When I click the Create Storage Account context menu item, the Create Storage Account dialog opens, providing an opportunity to specify the Storage Account’s name that I’d like to create. I’ll also select the same region that will house my Azure Website, placing both the Website and the Storage Account into the same geographical region.
Once the storage account has been created I’ll right-click on it to get the storage account properties.
When the properties panel opens, I’ll click the ellipse button next to the Connection String property in the panel.
The Storage Account Connection String dialog will open, providing me an opportunity to copy the Storage Account’s connection string to my clipboard.
Now I’ll create two connection strings to configure WebJobs’ connectivity in my Website named AzureWebJobsStorage and AzureWebJobsDashboard, and I’ll paste in the connection string I copied earlier as the value of the connection string. The final step is to select Custom from the Database Type column in the Website Settings panel.
Now that the Web Application and WebJobs are published and configured, I’ll use the new Server Explorer tools for WebJobs and the remote debugging features to make sure everything is operating properly.
Managing and Debugging WebJobs using the Server Explorer
Now that the Web Application Project and accompanying WebJobs have been deployed, I’m going to want to debug into my continuous job to make sure it is working as expected and designed. To get a deeper dive into how the WebJob is executing, I’ll set a breakpoint in the continuous job’s code.
Some of the WebJobs-related features we’re most proud of are visible in the Server Explorer. Underneath each Website node in Server Explorer, we’ve added a folder grouping to all of the associated WebJobs. To make the jobs easier to locate in the tree we’ve grouped them by continuous and on-demand or scheduled. We’ve hung various context menu items from the WebJobs nodes’ context menu that are appropriate for the type of WebJob being clicked. I’ll use the Start menu gesture from the continuous WebJob node to start up my continuous WebJob.
Now that the WebJob has been started, I’ll use the Attach Debugger menu item to attach the Visual Studio debugger to the WebJob running in Azure. Once I click this menu item, Visual Studio will attach to the remote debugger running in Azure Websites, and attach the debugger to the WebJob’s EXE.
Once the Continuous WebJob is running and the debugger attached, I can use the Scheduled/On-demand WebJob context gesture to start the on-demand job, which will send a message into the Azure Storage queue my Continuous WebJob is watching. The on-demand job will wake up and drop a message into the Azure Storage Queue.
Once the on-demand job drops a message into the Azure Storage queue being watched by the continuous WebJob and the message is picked up and processed by the WebJobs SDK, the contents of the message is visible in the debugger’s watch window. Even though the code for my WebJob is actually running live in Azure, I’m able to debug the code locally within Visual Studio from my development workstation, giving me a deep level of visibility into how the WebJob code is executing in the cloud!
With the Visual Studio Update 4 and Azure SDK 2.5 releases we’ve greatly expanded our investment into making it easier than ever before for web developers to add background processing to their Websites. We’ve taken steps toward providing a greater level of control over the WebJobs running in an Azure Website, and we’ve provided deeper diagnostics and debugging features so that developers have great visibility into how their code is running in Azure. We hope you enjoy these new features and that you learn more about what’s available in the Azure WebJobs SDK to extend this functionality. Have fun adding background processing to your ASP.NET Web Applications with Azure WebJobs!