I have been developing a CSS background image spriting, merging and minification application where I often force an app pool recycle in my integration tests. This is handy because it essentially allows me to reset the state of a web application in my test and it is a bit more light weight than performing a full IIS reset. I can specifically test certain scenarios where I want to make sure that some data or state can be persisted if the application is shut down. Its also a good way to isolate a test case from the effects of other integration tests. Things like output caching or any staticly held application memory resources are flushed and the next test has a clean slate.
To perform an app pool refresh, I use the following helper method in a class called IntegrationFactHelper:
public static void RecyclePool(){ using (var pool = new DirectoryEntry("IIS://localhost/W3SVC/AppPools/RequestReduce")) { pool.Invoke("Recycle", null); } Thread.Sleep(2000);}
Make sure you have a using statement pulling in the System.DirectoryServices namespace. The path above (IIS://localhost/W3SVC/AppPools/RequestReduce) would be the path to your IIS application pool. Note this is the IIS application and not the IIS site.
I'm not too proud of the Thread.Sleep(2000) here. I just have not invested time in a better way to actually wait for the pool to restart. The call to Invoke does not block and wait for the restart to complete. I briefly played with polling the application state but still found that after the application claimed to be on (or whatever the state name is) that the app was unresponsive. I tend to think that I have not investigated that far enough and would be delighted if someone commented with a way to more elegantly accomplish this. Having said that, I have found that on my system, 2 seconds is the sweet spot.
UPDATE: See this post for an improved implementation that avoids this Thread.Sleep kludge and also gets around the dependency discussed below.
One cautionary and rather annoying note on using this DirectoryServices call on IIS applications. You may encounter this not so delightful error:
System.Runtime.InteropServices.COMException : Unknown error (0x80005000) at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) at System.DirectoryServices.DirectoryEntry.Bind() at System.DirectoryServices.DirectoryEntry.get_NativeObject() at System.DirectoryServices.DirectoryEntry.Invoke(String methodName, Object[] args)
Isn't that nice? I love unknown errors...almost as much as unspecified ones.
There may be other causes, but I have found that one reason this error may occur is if you have not enabled the Windows feature: IIS Metabase and IIS 6 configuration compatibility (see image below). I am using IIS 7, but this feature is required to use the above code.