Avoid IISRESET in ASP.NET applications (added bonus: ASPRESET)
I'm always a bit worried when I work with developers or system admins that still think you should "throw in an IISRESET just in case" when deploying ASP.NET applications. Cargo cult server administration at its worst ("Not sure why, but it always seems to help if I throw in an IISRESET after pushing code. If that don't get it, a reboot will!").
This is very rarely necessary now, and it's terrible to take all websites on a server offline "just in case". It was often needed back in the ASP / COM days (you needed to free the reference to COM objects to allow overwriting the files), but ASP.NET code runs under the ASP.NET worker process and runs with side-by-side support, which completely obviates the IISRESET step. Copy the files and go!
If your changes include files which will restart the web application (such as DLL's or the web.config file), the site will automatically restart. You're done.
If, on the other hand, you've edited other files which don't cause a website restart (such as .config files referenced from web.config, etc.) you'll have to trigger the site to reload manually. There are at least 4 ways to force an ASP.NET website to recycle:
-
Edit web.config - open it in notepad, add a space, remove the space, and save. The change to the file timestamp will cause the site to reload.
-
"Touch" the file to change the file timestamp. I wrote a reg file that adds a "right click / Touch" menu item a while ago for just this purpose. There are other more advanced Touch utilities such as the one Scott Hanselman mentions here.
-
Kill ASPNET worker process manually. Don't be scared - it will automatically restart on the next request.1 It will dump the current requests (and possibly session state if you're inproc), but so will all of these. The ASPNET worker process is a cockroach; it keeps coming back. You just bring up the task manager, go to the Processes tab, find your ASP.NET worker process (aspnet_wp.exe for XP and W2K, w3wp.exe for W2K3 and Vista), right-click it and select "End Process". It will restart on the next request to an ASP.NET page.
- A new one - ASPRESET. All the above methods are more work than Start / Run / IISRESET, which means people will be more likely to fall back to their old habits and run that IISRESET. The following code (compiled and saved as ASPRESET.exe and saved in a folder in your path) will kill the ASP.NET worker process and restart it immediately by requesting a phony page with a .ASPX extention. That's expecially handy if you build ASP.NET in Visual Studio as non-web projects, since you need a running process to attach to when you debug. I keep the compiled executable in a
I built this in SnippetCompiler, but it will work just fine in Visual Studio 2003 and 2005 as well.
using System.Diagnostics;
using System.Net;
public class AspReset
{
public static void Main()
{
KillAspNetProcess();
StartAspNetProcess();
}
private static void KillAspNetProcess()
{
string processName = "aspnet_wp";
System.OperatingSystem os = System.Environment.OSVersion;
//Longhorn and Windows Server 2003 use w3wp.exe
if((os.Version.Major == 5 && os.Version.Minor > 1) || os.Version.Major ==6)
processName = "w3wp";
foreach(Process process in Process.GetProcessesByName(processName))
{
Console.WriteLine("Killing ASP.NET worker process (Process ID:" + process.Id + ")");
process.Kill();
}
}
private static void StartAspNetProcess()
{
try
{
string phonyURL = "http://localhost/directory/does/not/exist/"
+ Guid.NewGuid().ToString()
+ "/start.aspx";
WebClient myWebClient = new WebClient();
byte[] myDataBuffer = myWebClient.DownloadData(phonyURL);
}
catch(System.Net.WebException)
{
Console.WriteLine("ASP.NET worker process restarted.");
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
1Caveat: Killing a process is a bit more risky than restarting the application by touching web.config, since it prevents ASP.NET from shutting down gracefully. If you've got non-transactional work going on (a really bad idea), you could theoretically leave things in a bad state. Any decent database system shouldn't have any problems - I'm talking about code which edits text file, etc. I've never had a problem with this, and I've been merciless to aspnet_wp for the past 3 years, but this is primarily something I use in my dev and stage environments. If your site can't handle a loss of power, you just might want to fix that...
I considered a phony edit to machine.config, which would have the same effect as editing all web.config files on the system, but I feel like that's higher risk than just killing ASP.NET worker process, since messing up machine.config will bring the server down until you fix it.
Of course, none of this is required with VS 2005 projects running under Cassini.
UPDATE: For another reason to avoid IISRESET, see Ken Robertson's post: IISReset corrupting the IIS metabase