Recycling an Application Pool with C# (Part 2)

28. July 2011 12:24 by Matt Wrock in   //  Tags:   //   Comments

The other day I shared how to use the DirectoryServices namespace to restart an app pool via C# code. The code I used had two key flaws:

  1. It used a Thread.Sleep(2000) to wait for the old app pool to be destroyed.
  2. The use of DirectoryServices required the enabling of the windows feature: IIS Metabase and IIS 6 configuration compatibility.

Also just to recap why you would even want to do this: My use of this code is for writing integration tests of web app functionality. It allows me to test scenarios where I want to ensure a certain outcome after the application restarts. It also helps to isolate test state from one test to another.

Anyhoo, a coworker of mine, @mmanela (Matt Manela) mentioned hosting a powershell script instead of the DirectoryServices implementation. As we discussed it further, we assumed that the PowerShell WebAdministrationiModule was probably using some other API and that it would be interesting to discover what that was and see if you could use that. Well after spending some quality time with reflector and the WebAdministrationModule DLLs, I was not able to tell what that API was. However, I did discover another API that appeared to be a better alternative to DirectoryServices.

The API can be found in %WinDir%\system32\Inetsrv\Microsoft.Web.Administration.dll. See this post for a good overview. Here is my new helper method:

public static void RecyclePool()
{
using (var manager = new ServerManager())
{
var pool = manager.ApplicationPools["RequestReduce"];
Process process = null;
if(pool.WorkerProcesses.Count > 0)
process = Process.GetProcessById(pool.WorkerProcesses[0].ProcessId);
pool.Recycle();
if(process != null)
{
while (!process.HasExited)
Thread.Sleep(0);
process.Dispose();
}
}
}

So in addition to using a different API, I’m also no longer using the hacky Thread.Sleep(2000) to wait for the app pool to die. Instead, I use this API to get the Process ID of the about to be recycled app pool. I then wait for the pool to exit. I have tested this and it works perfectly. So now my tests move on as soon as the app pool is completely destroyed. I don’t have to wait any extra time in case this happens more quickly than two seconds and I don’t risk a failed test if two seconds is not long enough. In case you are wondering why it is so important to wait for the old app pool’s worker process to terminate before proceeding, it is because I may have cleanup code that deletes files and that code will likely fail if the old worker process had a lock on the file.
blog comments powered by Disqus

About Me

Hey thats me!

I'm Matt Wrock with over thirteen years of experience architecting scalable, distributed, high traffic web applications. I currently live in Woodinville, WA with my wife, two daughters, three dogs and cat. I work for Microsoft as a Sr. Software Engineer working in Cloud Developer Services. I'm also project founder and owner of http://www.requestreduce.org and a committer to http://chocolatey.org.

Month List