Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 7

Hi Everyone,

Welcome back!!!

Again, continuing to discuss the automatic dynamic page compilation further. Now we have been saying all the while that ASP.Net will detect automatically at runtime when ASP.Net resources change and will dynamically create new assemblies. Let's see how this replacement of assemblies happens.

How ASP.NET Replaces Page Assemblies:

We already mentioned that ASP.Net puts in place a file change notification mechanism and that is what tells ASP.net that a resource got updated and a new assembly is built for that. When a new assembly is created for a page as the result of an update, ASP.NET verifies whether the old assembly can be deleted. If the assembly containing the old page class contains only that page class, ASP.NET attempts to delete the assembly. Often, though, it finds the file loaded and locked, and the deletion fails. In this case, the old assembly is renamed by adding a .delete extension. (All executables loaded in Microsoft Windows can be renamed at any time, but they cannot be deleted until they are released.) Renaming an assembly in use is no big deal in this case because the image of the executable is already loaded in memory and there will be no need to reload it later. The file, in fact, is destined for deletion. Notice that .delete files will actually be cleaned up when the application is restarted next and that can happen due to various reasons, some of which are as follows:

  1. An application file (global.asax or web.config) change
  2. When the number of such recompilations as above exceeds the limit specified by <compilation numRecompilesBeforeAppRestart=... />
  3. Modification of the physical path of a virtual directory
  4. Modification of the code-access security policy

numRecompilesBeforeAppRestart:

Other reasons of application restart are quite understandable, let's understand this numRecompilesBeforeAppRestart a bit. When a page is recompiled, the assembly representing its old version stays in memory until the AppDomain is unloaded. There's no way this assembly can be freed up because this is one of the pillars of the whole CLR machinery. To avoid having too many recompiles flood the memory with too many assemblies (all of which are useless), the ASP.NET runtime periodically restarts the application and imposes an upper limit to the number of allowed recompiles. Each ASP.NET application is allowed a maximum number of recompiles (with 15 as the default) before the whole application is restarted. The threshold value is set in the configuration file. If the latest compilation exceeds the threshold, the AppDomain is unloaded, and an application shutdown is scheduled to occur as soon as possible. Bear in mind that the atomic unit of code you can unload in the common language runtime (CLR) is the AppDomain, not the assembly. Put another way, you can't unload a single assembly without unloading the whole AppDomain.

In order to understand this further let us take a hypothetic example. Let's say we have an ASP.Net application and inside an ASPX page we write some code to access the AppDomain ID and the total number of assemblies present currently in the AppDomain of that ASP.Net application. This can easily be done using code as follows:

String appDomainID = HttpRuntime.AppDomainId.ToString();

System.Reflection.Assembly[] listOfAssem = AppDomain.CurrentDomain.GetAssemblies();

Response.Write(string.Format("AppDomainId: {0}<br />listOfAssem: {1}",appDomainID, listOfAssem.Length));

Now again, let us say as an example the sample page needs 10 system assemblies, including those specific to the application—global.asax and the page class. This number increases each time you save the .aspx file because after a page update, a new assembly is loaded, but the old one is not unloaded until the whole AppDomain is unloaded. If you save the .aspx file several times (by just opening the file and pressing Ctrl+S), we can easily see that the output of above code will keep increasing each time by to 11, 12, etc. But after 15 recompiles (with the default setting), the AppDomain ID will change – that is as soon as the number of loaded assemblies become 25, and immediately the number of loaded assemblies will revert back to 17 or whatever it was originally. This number, in fact, depends upon the number of referenced assemblies you included with your page.

That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow we will take another example, a bit more realistic one and will try to apply all the dynamic compilation concepts we learnt so far and that should be it for dynamic compilation. The upcoming next dive would be inside application pre-compilation.

Thanks,

Sukesh Khare

Coordinator Daily .Net Feed Program