views:

1034

answers:

5

I have an ASP.NET 2.0 application (installed on IIS 6.0 from an MSI) which was compiled as a "web site", and precompiled/packaged using a web deployment project, in Visual Studio 2005. (I have put in a request to the developers to consider changing to a web application for the next version, but it won't change for this version).

Whenever the application is recycled (e.g. a change is made to the web.config), on first hit, ASP.NET JITs the application. As part of this, it takes all the assemblies required for the login page and compiles them into native code in the Temporary ASP.NET Files 'assembly\dl3' directory, which takes between 20 and 60 seconds. This only happens on a recycle, which happens infrequently — but when it does, it causes the page to take much longer to load, and I believe it may be possible to optimize this.

There appear to be 122 DLLs that it needs to consider, some of which are the precompiled code-behind, others are third party components for the web site (for example, NHibernate.dll, reporting components, etc.)

Why does it recompile/re-JIT everything? Why does it not detect that most of the assemblies have not changed, and not attempt to change them? Can I prove it's not batch compilation that is causing the problem? (I have <compilation debug="false"> set in the web.config.)

Other questions suggest NGEN might be useful but I read it's not possible to use it on ASP.NET 1.x; we are using 2.0 and I can't find a clean answer either way.

+2  A: 

Are you running IIS? I'm fairly certain that if you restart your site in IIS it will pick up any changes to configs without copying the dlls.

Matt Grande
Yes, the application is running under IIS 6.0. The action of changing the config causes it to re-copy all the DLLs; I'm not sure if you make the change with IIS stopped, what the output is.
crb
Hmm, really. Well then, nevermind. (I have very little IIS experience, and have only used IIS7)
Matt Grande
A: 

It's strange that only copying the dll takes 20 seconds. I would suggest to do another check and make sure where the bottleneck is.

Albert
It's not one DLL, it's 122 of them. 26MB worth. That will always take some time; my point was I'd rather not do it if they have not changed!
crb
In a standard HD 26MB should be copied in 2-3 seconds. I guess the problem is the pre-compilation of the application and all the initialization code you may have in application startup.
Albert
You're right, it did copy the directory in about that time. However, I can't tell what else it is doing at the time, from anything other than the Process Monitor output, so I'm interested in other ideas...
crb
I don't think you can do much about it, unless you have some heavy code in Application_Start() and you can improve it...
Albert
+2  A: 

You may be able to improve your recycle time by installing common DLLs that change infrequently -- such as NHibernate or reporting tools -- into the GAC. That should prevent them from being re-jitted.

How to: Install an Assembly into the Global Assembly Cache

Skirwan
+2  A: 

From my personal experience slow recycle is often caused by NHibernate/ActiveRecord if you have lots of entities. See http://nhforge.org/blogs/nhibernate/archive/2009/03/13/an-improvement-on-sessionfactory-initialization.aspx for explanation + possible solution.

felixg
Nice find, +1. I'm trying to find a patch for NH (we don't use Castle) to see if we can get the gain here also. Might you happen to have one?
crb
Unfortunately no, but I'll try to add it to Fluent NHibernate soon. No promises though.
felixg
Heh. All these fixes in newer NH patterns that I can't use in the old version of our commercial product. I much prefer the OSS quick-update world :)
crb
A: 

How can you be certain that everything is in the proper state without recycling/resetting (or whatever happens) the AppDomain? Imaging that you have something in application start (global.asax) which sets the value of a static field based on a config value. Unless you reset the entire AppDomain you cannot be sure.

Another reason: There is no way to unload a .NET dll once its loaded, so you have to recreate the app domain when something is updated.

JMD