← Back to overview
November 5, 2012 · IIS 8 Web Role

IIS 8.0 Application Initialization module in a Windows Azure Web Role

Back in 2009 the IIS team announced the beta release of the Application Warm-Up Module as a downloadable extension. Today this module was renamed to Application Initialization andis included in IIS8. Activating it will add a few interesting capabilities to your IIS installation:

The first two features are important in terms of performance. After starting the World Wide Web service, it will start the application pool and initialize your application. In most cases, this means that the first users visiting your site won't have to wait until the application starts, because application was already started and initialized.In addition to automatically starting the application, this will also improve the 'recycle experience'. When your application pool is being recycled, a new worker process will be started. But with the preloadEnabled setting, the new worker process will only start receiving requests when the application is completely initialized. Wade Hilmo wrote a great introduction to Application Initialization on his blog.

In case your application takes a long time to start (SharePoint 2010 or Dynamics CRM 2011 for example), you can provide your users with a better experience. Using an URL rewrite you can show a loading page while the application is starting. The IIS team blogged about this a while ago and as you can see it's pretty simple to set this up:

    <rule name="Home Page-Expanded" stopProcessing="true">
      <match url="default.aspx" />
        <add input="{APP_WARMING_UP}" pattern="1" />
      <action type="Rewrite" url="Startup.htm" />
    <rule name="Home Page-Short" stopProcessing="true">
      <match url="^$" />
        <add input="{APP_WARMING_UP}" pattern="1" />
      <action type="Rewrite" url="Startup.htm" />
    <rule name="All Other Requests">
      <match url=".*" />
        <add input="{APP_WARMING_UP}" pattern="1" />
        <set name="SKIP_MANAGED_MODULES" value="0" />
      <action type="Rewrite" url="{URL}" />

Installing Application Initialization

Let's see how we can bring this to a Windows Azure Web Role. We'll create a simple application that deploys to Windows Azure, enables the Application Initialization module in IIS and configures the site and the application pool. The first thing we'll do is create a new Cloud Service targeting the .NET Framework 4.5. As a result, the osFamily in the ServiceConfiguration.cscfg will be set to 3. This means you'll be deploying a Web Role on Windows Server 2012.

The Application Initializationmodule is part of IIS8 but isn't activated by default. In order to activate this module, we'll need to write a startup task that runs pkgmgr.exe (a tool that allows you to install Windows Server Roles and Features through the command line). The only problem is that we don't know the name of the Application Initialization feature required by pkgmgr.exe. After digging in the registry I found the following key:

With this information I could simply create a startup task that adds this feature to the current IIS8 installation:

Echo Installing Application Initialization  
PKGMGR.EXE /iu:IIS-ApplicationInit  

And here is the result:

Configuring the application

The module has been installed, but how do we configure the website and the application pool? We have to do this on the right moment since IIS needs to be started and the Web Role's website(s) need to be configured properly. That's why I don't like using a startup task for this since most of the time your websites haven't been configured when it runs. Instead of using a startup task, we'll write some code in the WebRole.cs. Since we'll be modifying some settings in IIS, we need to make sure the code in WebRole.cs runs in an elevated process. This is possible by adding the following line in the ServiceDefinition.csdef:

<?xml version="1.0" encoding="utf-8"?>  
<ServiceDefinition name="AppInitDemo" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2012-10.1.8">  
  <WebRole name="WebRole1" vmsize="Small">
    <Runtime executionContext="elevated" />

Now simply add a reference to Microsoft.Web.Administration (which can be found inC:\Windows\System32\inetsrv) and write the following code (this won't work if you're debugging locally with IIS Express):

    public class WebRole : RoleEntryPoint
        public override void Run()
            using (var serverManager = new ServerManager())
                var mainSite = serverManager.Sites[RoleEnvironment.CurrentRoleInstance.Id + "_Web"];
                var mainApplication = mainSite.Applications["/"];
                mainApplication["preloadEnabled"] = true;

                var mainApplicationPool = serverManager.ApplicationPools[mainApplication.ApplicationPoolName];
                mainApplicationPool["startMode"] = "AlwaysRunning";



        public override bool OnStart()
            // For information on handling configuration changes
            // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

            return base.OnStart();

This code will connect to IIS and set 2 attributes:

Finally calling CommitChanges will save these settings. If you activate Remote Desktop and you connect to your Web Role you'll see that thew3wp.exe process is already running:

Setting up the splash screen

I've modified the Global.asax file to simulate some work while the application is starting. Using Thread.Sleep it will take 30 seconds for the application to start:

    public class Global : HttpApplication
        void Application_Start(object sender, EventArgs e)
            Thread.Sleep(10 * 1000);

        void Application_End(object sender, EventArgs e)
            //  Code that runs on application shutdown


        void Application_Error(object sender, EventArgs e)
            // Code that runs when an unhandled error occurs


` In case users start connecting while the application is starting we can show a splash screen thanks to the Application Initialization module. Besides using url rewrites you can configure the Application Initialization module directly in the web.config. Here I'm showing Loading.htm while the application is starting:

    <applicationInitialization remapManagedRequestsTo="Loading.htm" skipManagedModules="true" >
      <add initializationPage="/" />

While the application is starting users will see the following page:

Once the application is ready, they'll see the actual application:

I'm assuming you'll want to test this. It seems that running iisreset does something which doesn't show the splash screen (I don't know if this is caused by Windows Azure or by IIS). But I noticed that restarting the Web Server manually through the UI does work:

That's it!

The complete application is available on GitHub:https://github.com/sandrinodimattia/WindowsAzure-IISApplicationInitializationModule

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket
Comments powered by Disqus