This post may sound like it’s for novices but deciding to pull this one out of my keyboard after facing few of these recently.
We, the people working in Asp.Net, love Sessions. I am sure everyone nods Yes. And just for that reason we put various kinds of data in the Session variable. Ranging for user names to their profile to list of items in an application to a table to entire database! Because it’s damn easy. You just have to do:
Session["MySecretPassword"] = "rohitjain";
or
Session["MySmallDatabase"] = dataSetDB;
And done! Now, You have your password or the entire database in session for a long long time. But! Here is a catch, what is this LONG time? Ahem, that depends on many things. Not going deeper into this but must to mention a reason that is Application Domain restart! Let’s talk ‘bout it & check out few reasons that restarts an asp.net application with some probable resolutions that I feel.
When an asp.net application restarts, it kills most of the things related, specially those which are volatile by nature, our beloved Session is one of those :(. And it not just kills things but it recompiles the application too which can take good amount of time and have thousands of your users waiting till then. Out-proc session storage may solve the vanishing of Session issue but still you can’t prevent Application restart.
There are few reasons that cause an Asp.Net application to Restart worth mentioning:
- Changes to web.config:
We all keep lots of application related info in web.config, specially Connection strings & appSettings keys. And they are kept their so that they can be changed easily when needed. But hey when I change anything, my application starts! I can’t force everyone connected to relogin/restart when I change my site header, or when I switch to a separate database.
- Resolution: Don’t change your values!
Ha ha ha. Just joking. Asp.net 2.0 upwards supports external configuration files. The best candidate is appSettings.config, which we update quite randomly. Just have an external file say appSettings.config and mark it as the source. For an example:
<appSettingsconfigSource="appSettings.config" />
That’s it. Now you will need an external file appSettings.config as below:
<appSettings>
<addkey="SiteHeader"value="Hello There!"/>
</appSettings>
And you are done. Now when you update this appSettings.config the application doesn’t restart, and you get the New values when you use AppSettings collection!!!
Everyone is happy! :-)
Though there are few conventions to be followed such as the path of the external file has to be relative to the root web.config file. For example it can be “appSettings.config” if the file is also in the root directory or “Configurations\appSetttings.config”, in case you want to keep all your external settings in a separate subdirectory.
You also have to ensure that the root node of the external file is same as the one you are using it for. Means? Means, if you are using an external file for appSettings section, the first node of the external file should be appSettings. And as you know its XML, it’s case sensitive.
And yes this is not just limited to appSettings sections. If you have your own custom configuration sections, you can externalize that too. For example, I have a custom section named as MyWidgetSettings which has few settings related to my site’s widgets layout. I have a section handler for that mentioned in the web.config. Now? Simple. Do the followings:
Move your settings to an external file, say Configurations\MyWidgetSettings.config. And make sure to have the same root element; in our case MyWidgetSettings.
<MyWidgetSettings>
<Settingname="vertical-alignment"value="left"/>
<Settingname="borderimage"value="~\img\wb.gif"/>
</MyWidgetSettings>
In the web.config edit your section:
<MyWidgetSettingsconfigSource="Configurations\MyWidgetSettings.config" />
Last and the most important, Update your section handler keys,
<configSections>
<sectionname="MyWidgetSettings"type=" SampleCodes.MyWidgetSettingsHandler, SampleCodes"restartOnExternalChanges="false"/>
</configSections>
I am sure that you have guessed that the magical key is restartOnExternalChanges="false" :)
For more details on other options on other tweaks and tricks related to this, just Google.
- Folders:
We all know how to create directory.
Directory.CreateDirectory("Dir1");
And it’s no crime. And in case these need to be deleted?
Directory.Delete("Dir1");
Bravo!
But you not only killed the directory, you killed the application too. Yes My Dear! And the same applies to renaming a directory too. Consequence: Application restart!
How does it happen? There is a service called “File Change Notification (FCN)” that runs at the background and notifies IIS when there are changes to the local file system.
- Resolution: Create but don’t destroy!
That’s the rule of thumb. You can create a directory inside your web directory but you MUST not delete any. You can delete the internal files but you have to leave all directories/subdirectories. But but but, In case you are environment friendly and feel that you really need to delete directories too and throw away unneeded trash, create directories outside the web directory anywhere. Any file system changes outside the web directory will not cause that application to restart (generally). There are other way outs like using Achieve files such as .zip instead of a folder to store files and use a tool to read and write to them. The recent .Net framework has inbuilt framework for that. But this way out doesn’t suit always, mostly not.
- Aspx file changes:
We all know that an application doesn’t start when we update an Aspx file (& hence recompiled). Not Actually! There is a count that goes behind the scenes. By default, an application doesn’t start till the count of dynamic recompiles reaches 15, a default value. Once reached it Does restart.
- Resolution: There is an element named compilation that comes under the configuration\system.web of a web.config.It has so many attributes one of which is called numRecompilesBeforeApprestart. It can be used to increase the default value (15) to an even higher value in case you update the files frequently. This will save you frequent application restart arising out of changes to aspx files.
- Application Idle time out:
An asp.net application domain recycles after sometimes (by default 20 minutes), if it’s left idle. That means if no one hits your application for 20 minutes straight, it will recycle the application. Mind you, this is different from Session timeout property. So, even if your session timeout happens at 60 minutes, and the application is left idle for 20 minutes. At the 21st minute, your session will be void too as the application would restart on the next request.
- Resolution:
You can change this timeout figure via IIS. This is an IIS configuration and is set via the properties of the Application Pool to which your application belongs. Play around with IIS and you will find other interesting features/settings too.
And yes…
There are many scenarios when you would like to Force an application restart. You don’t need to go and edit web.config to cause it, just have a page with following code:
System.Web.HttpRuntime.UnloadAppDomain();
And call that page by any means. Make sure that not any Tom, Dick or Harry can access this page :)
This is a very very partial list of so many other reasons that can cause an application to restart. But just mentioning few ones faced recently. If you have faced something like this & would like to share, just drop it as a comment.
Hope it helps.