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;
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