Blog Post by Murat Yaşar


Posted on Thursday, February 04, 2010 4:58:51 PM and it has been read 8336 times since then.


Asp.Net Application Warm Up By Using Windows Service

When you make a request for a page from any Asp.Net application, it takes server some time to respond your request. During this waiting period, some server side tasks happen.

Application Life Cycle in General According to MSDN:
1-)User requests an application resource from the Web server.
2-)ASP.NET receives the first request for the application.
3-)ASP.NET core objects are created for each request.
4-)An HttpApplication object is assigned to the request.
5-)The request is processed by the HttpApplication pipeline.

When a request is made to an application the first time, ASP.NET compiles application items. This first request's response can be slow due to compiling process which is being done by ASP.NET. After this compilation process, the subsequent requests can get faster response than the first time response.

But if any of the following happens, this compilation process takes place again, in other words they will cause an application restart.
* When you modify the source code of your Web application.
* When you add, delete or modify assemblies from the application's Bin folder.
* When you add, delete or modify localization resources from the App_GlobalResources or App_LocalResources folders.
* When you add, delete or modify application's Global.asax file.
* When you add, delete or modify source code files in the App_Code directory.
* When you add, delete or modify Profile configuration.
* When you add, delete or modify Web service references in the App_WebReferences directory.
* When you add, delete or modify the application's Web.config file.

Take a look at the following links to get more information about this life cycle:
https://msdn.microsoft.com/en-us/library/ms178473.aspx
https://msdn.microsoft.com/en-us/library/bb470252.aspx

All pending requests will be served by the existing application domain and the old assemblies before restarting application domain, if an application restart is required.

Other than above items, an application pool can be restarted according to its own settings.

When this application restart happens, we have to wait for some time to get response from the server if we hit it the first time. Waiting can be tolerable in some cases but not all the time. The application could be very important or just annoys us to wait to get response from the application. Furthermore, do you think the visitors are patient enough to wait?

There is a good news for this situation. If you use ASP.NET 4.0 and IIS 7.5 you can set a few variable and it is done. "ASP.NET 4 ships with a new feature called 'auto-start' that better addresses this scenario, and is available when ASP.NET 4 runs on IIS 7.5 (which ships with Windows 7 and Windows Server 2008 R2).  The auto-start feature provides a controlled approach for starting up an application worker process, initializing an ASP.NET application, and then accepting HTTP requests."

The above line from http://weblogs.asp.net/scottgu/auto-start-asp-net-applications-vs-2010-and-net-4-0-series page where Scott Guthrie talks about this specific issue.

If you serve your application from shared hosting environment and do not have much control over application pool settings, moreover you can not set isolated application pool for your application and other application causes to restart the application pool you are in and as a result you have to wait after each application pool restarting in the server. There is a solution they can offer you but what if you do not want to pay extra money for this.

While I was thinking possible solution for this, I thought if I could create a request periodically to my application, I would not get a late response. Because I might be able to warm up my application without waiting the first request to hit my app.

Afterwards I started thinking about a way of creating request automatically. I thought that a windows service might be very useful. What I did was basically I built a windows service which creates a request to URL's. The URL addresses are read from an xml file called settings.xml.

Not very efficient but you can kind of get an information about your web application up time by inspecting logs that the service keeps. If you look at the source code you will see that a status code returns from each requests. If certain code is not returned, we take them as error and wrote its code into log.

Even though the solution seems appropriate, there is one drawback. We need a machine which will run continuously with an internet connection.

Now, I am going to try to explain each step I have taken and you should as well if you want to apply this solution. All files, executables, images used in this article are downloadable and you can see those files at the end of this writing.

This settings.xml file should be at the same path where service's executable file stays. You can write as many URL addresses as you want create request to, enable or disable logging, specify how often we should create request to URL. All these settings can be done inside settings.xml file.


I wrote this windows service by using;
-----------------------------------------------------
Microsoft Visual Studio 2008
Version 9.0.30729.1 SP
Microsoft .NET Framework
Version 3.5 SP1
on Windows Vista Home Premium Service Pack 2


Following is the settings.xml file that the service are reading from.

<!--?xml version="1.0" encoding="utf-8" ?-->
<mysettings>
	<!-- If we want to keep the log files, we should set 1 otherwise 0. -->
	<enablelogging>
		<enable>1</enable>
	</enablelogging>
	
	<!-- Write the web site URLs that you want to warmup periodically. -->
	<whichsites>
		<website>http://www.yasarmurat.com</website>
	</whichsites>
	<whichsites>
		<website>http://www.microsoft.com</website>
	</whichsites>
	<whichsites>
		<website>http://www.google.com</website>
	</whichsites>
	<whichsites>
		<website>http://www.xyz.com</website>
	</whichsites>
	
	<!-- How often warmup process will work. (In minutes) -->
	<howoftenarewegoingtocheck>
		<howofteninminutes>3</howofteninminutes>
	</howoftenarewegoingtocheck>
</mysettings>

You can add as many web sites as you like by adding following tags into settings.xml file.

<whichsites>
	<website>http://www.yasarmurat.com</website>
</whichsites>

Main part of this service is below. It simply creates a web request and takes response from the server. More detailed method is in solution file.

System.Net.HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Convert.ToString(hashWhichSitesSpecification[@"WhichSites_" + i.ToString()]));
request.Credentials = CredentialCache.DefaultCredentials;
request.Method = @"GET";
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

You can download either Visual Studio Solution File or just the necessary files to install and use this service. If you want to download solution file, click on WarmUpAspNetApp.rar or just want to download the necessary files, click on AspNetWarmUpService.rar at the end of this writing.

Before starting install the service I assume that you have copied the necessary folder into root of C drive as follows.
C:\AspNetWarmUpService
Following are the files which are needed to be inside this folder.
C:\AspNetWarmUpService\installService.bat
C:\AspNetWarmUpService\uninstallService.bat
C:\AspNetWarmUpService\WarmUpAspNetApp.exe
C:\AspNetWarmUpService\WarmUpAspNetApp.pdb
C:\AspNetWarmUpService\WarmUpAspNetApp.vshost.exe
C:\AspNetWarmUpService\WarmUpAspNetApp.vshost.exe.manifest
C:\AspNetWarmUpService\settings.xml


Now, we can install the windows service as follows:
-----------------------------------------------------------------------
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe C:\AspNetWarmUpService\WarmUpAspNetApp.exe

Here I assume that you have already installed .NET framework and placed the folder named AspNetWarmUpService under C drive.

In case you need to remove this service, the following is the way to do this. Uninstalling service:
-------------------------------------------------------------------------------------------------------------------------------------
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe /u C:\AspNetWarmUpService\WarmUpAspNetApp.exe

As you can guess, this is command line where we run above lines. You must to open cmd.exe with Administrator privilege. If you do not, you will not be able to install or uninstall the windows service successfully. To be able to run command line with administrator privilege, you can do one of the followings:

Method A-)
1. Press the Win keyboard key or click on Vista Start button.
2. Type cmd into the Start Search textbox.
3. Press Ctrl+Shift+Enter keyboard shortcut. Ctrl-Shift-Enter is the general keyboard shortcut that triggers elevation to Run as Administrator.
4. Press Alt+C or press Continue to confirm the UAC elevation warning prompt.

Method B-)
1. Click on Vista Start button.
2. In the Start Search box, type in Cmd (without quotes).
3. Right click on the Command Prompt in the search result listing.
4. In the right click menu, click on the Run as Administrator menu item.

After installing the windows service, we need to set up some properties of this service in order to run it properly.
* Click on Vista Start button.
* In the Start Search box, type in services.msc (without quotes).
* If warning prompt appears, say continue.
* Go to bottom and find WarmUpAspNet service.
* Right click on it and choose properties.
* Make sure startup type is set to Automatic. (It should be by default.)
* Go to Recovery section and choose "Restart the Service" for first, second and subsequent failures.
* Click Apply and OK.
* Right click on the service and choose "Start" for starting the service.

Setting "Restart the Service" for 3 type of failures is very important. If you do not do this, service will not be able to restart itself, if something goes wrong while it is running. Also every 10 hours, service is being restarted in case any memory leak.

/BlogEntryImages/33/ServiceProperties_Recovery.jpg

These 3 has to be set "Restart the Service" otherwise the service will not work as it is expected.

After waiting the time you specified in settings.xml file between 3 tags, you should be able to see the log inside event viewer with the key "WarmUpAspNetApp Service". Again I assume you have enough privilege to write into event viewer. I use Windows Event Viewer to keep log on these requests. You can implement some other mechanism while you have the source code. Writing into txt file, or sending an e-mail when an error occurs or something else you appreciate with.

If you do any changing in settings.xml file, you must restart the service manually in order to take effect those changes. Otherwise, it will take effect after the service restarted by its logic.

I will try to update this if I see something not very well explained or missing.

Have a great day.


- Downloadable File/s -
File Name File Size Description
aspnetwarmupservice.zip 20.428 KB It contains only the necessary files in order to install windows service. Download
aspnetwarmupservice.rar 18.836 KB It contains only the necessary files in order to install windows service. Download
images.zip 686.739 KB You can see the screenshots by downloaind this file. Download
images.rar 678.378 KB You can see the screenshots by downloaind this file. Download
warmupaspnetapp.zip 81.881 KB This is the solution file. You can see the source code of this service application. Download
warmupaspnetapp.rar 77.691 KB This is the solution file. You can see the source code of this service application. Download

(In order to use this feature, you have to register.)


  • Murat Yasar
    Murat Yasar | Reply
    Tuesday, February 09, 2010 8:33:37 PM

    Also by default application pool is set to recycle the Application Pool every 1740 minutes. That makes first access slower than the subsequent requests.

    Another thing keep in mind is if the application pool was set to shut down after 20 minutes of inactivity, each person using the application would likely report that response is quite slow on the first access, but good after that.


    • p.joos
      p.joos | Reply
      Thursday, September 30, 2010 11:36:31 AM

      nice idea but...
      i wanted to have a look into it and had to notice that none of your links seems to be working

      i hope thats just a temporarily problem.

      best regards


  • Murat Yasar
    Murat Yasar | Reply
    Thursday, September 30, 2010 8:19:39 PM

    Problem about downloading attachments has been fixed.

    Regards.


  • carmen cismas
    carmen cismas | Reply
    Friday, May 27, 2011 1:21:46 PM

    Hello,

    The idea is great. I`ve tested and it works perfectly, but i do have an issue: it does not work on SSL (https) sites.
    Do you have any idea on how to make it work?

    Have a great day,
    Carmen


    • Murat Yasar
      Murat Yasar | Reply
      Friday, May 27, 2011 7:13:51 PM

      Hello Carmen,
      At the time I needed this solution, I did not take into account SSL sites.

      I am sure there is a way for making it work for SSL sites as well. If I get enough free time, I will take a look for this but if you find out any fix or solution for this service to make it work against SSL sites, please write here as comment.

      I love learning new things.

      Thanks and have a great day.


    • Murat Yasar
      Murat Yasar | Reply
      Sunday, May 29, 2011 9:28:40 AM

      Hello again,

      I just took a look and made some googling on this issue.

      These are the few links which might be helpful. I haven't tried it whether they work or not but according to them this could be the solution. Please check the following two links. If you get a successful result let me know.

      http://stackoverflow.com/questions/560804/how-do-i-use-webrequest-to-access-an-ssl-encrypted-site-using-https


      http://www.pcreview.co.uk/forums/connect-ssl-site-using-webrequest-t2442529.html

      Have a great day.