← Back to overview
October 29, 2013 · App Suspend IIS8 Web Role

Using ASP.NET App Suspend in your Windows Azure Web Roles (OS Family 4)

Windows Server 2012 R2 was released about 2 weeks ago together with Visual Studio 2013 and the .NET Framework 4.5.1. One of the updated features in Windows Server 2012 R2 is IIS 8.5 which introduces the Idle Worker Process Page-out functionality, adding suspend support to your application pools. This is similar to the tombstoning support in Windows Phone / Windows Store applications.

ASP.NET App Suspend is the managed implementation of this new functionality and will improve the startup time of your .NET web applications running in IIS. The .NET Framework Blog explains that this is perfect for hosting companies but even if you're only running a single site you'll feel the difference.

Let's take a look at some numbers…

Without App Suspend

So I deployed a simple ASP.NET MVC application as a Windows Azure Web Role and I'm hitting it for the first time. The first time I visit the application it takes 3.39 seconds to load the page (this is because the application needs to start for the first time).

Now after this first request the application pool has been "warmed up" and as you can see all other requests execute very fast. In this case it took about 26 ms:

The page load time will remain like this until the application pool recycles. Let's wait until that happens (for testing purposes I changed the Idle Timeout to 1 minute). In the next screenshot you'll see what you would expect:

After an application pool recycle the application needs to reinitialize and initial load is similar to the one we've see in the first step.

With App Suspend

Let's take a look at what happens when we enable App Suspend. The very first request still takes a few seconds to load.

There's nothing special about the second request either, it's still very fast.

Now for the last test we wait until the application pool recycles and try hitting it again. And this is where you'll see App Suspend kicking in. Thanks to App Suspend the application wasn't terminated but it was suspended instead. This reduced the application pool load time from 3.41 seconds to 41 milliseconds. The very first request will always take some time, but after you'll notice the reduced startup time.

App Suspend in your Web Role

Now let's see how we can enable App Suspend for web applications running in a Web Role.

Since this feature depends on IIS8 you'll need to make sure that your application runs on OS Family 4 (Windows Server 2012 R2). The OS Family of your project can be changed in the ServiceConfiguration.*.cscfg files:


The next thing we need to do is reference the Microsoft.Web.Administration NuGet package (make sure that Copy Local is set to true). This is because we'll be writing some code to enable App Suspend on our application pool. But before we can do that we need to make sure that the Web Role process (which runs the code in WebRole.cs) has sufficient permissions to access IIS. This is possible by changing the execution context of the role to elevated in the ServiceDefinition.csdef file:

The last thing we need to do is write the code that will enable App Suspend for the application pool:

public class WebRole : RoleEntryPoint  
{
    public override bool OnStart()
    {
        using (var serverManager = new ServerManager())
        {
            var applicationPoolName = serverManager
                    .Sites[RoleEnvironment.CurrentRoleInstance.Id + "_Web"].Applications["/"].ApplicationPoolName;

            // Update application pool (0 = Terminate / 1 = Suspend).
            var processModel = serverManager.ApplicationPools[applicationPoolName].ProcessModel;
            processModel["idleTimeoutAction"] = 1;
            // processModel["idleTimeout"] = TimeSpan.FromMinutes(1);

            // Save changes.
            serverManager.CommitChanges();
        }

        return base.OnStart();
    } 
}

Based on the name of the current instance we're able to find the main site with its application pool. Once we have the name of the application pool we can access the ProcessModel which allows us to specify the idleTimeoutAction. By setting this to 1 and saving the changes we've activated App Suspend. If you want to test if it really works I suggest you uncomment the line which specifies the idleTimeout. By uncommenting that line you'll be changing the idle timeout to 1 minute, which is low enough to test application pool recycles.

Enjoy!

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