ASP.Net JIT Compiler - asp.net

I am experiencing slow response times on a web server hosting several asp.net applications. I do not precompile my apps so I understand that the first request to an application will take some time to load (5 to 10 secs). However, if an application has been idle for some time (20-30 minutes) the response is still slow even though I have set the "Idle Timeout" to 0 for the app pool in IIS 7.5. Therefore, I am considering writing a Windows service that will send requests to the individual apps every 10 minutes to keep them alive. My question is how does the JIT compiler handle subdirectories in an app. Does the JIT compiler compile all code for an app when you request a single page or does it do just enough to process the current request?
So when I write the Windows service can I just send a request to a single page in the app or do I need to send a request to a page in each subdirectory as well?
Thanks.

The model ASP.NET generally uses creates separate assemblies for the contents of the App_Code directory as well as the global.asax file, and then compiles all of the .aspx pages in each directory into a separate assembly (upon request).
User controls and Master Pages are also typically compiled independently from .aspx pages. I'm assuming you're using the "Updateable" option when you deploy. In that case
the app_code folder gets compiled at
deployment time
Code behind files for .aspx and master pages are compiled at deployment time
For each directory - all code behind files are complied into separate assemblies at deployment time
If you have a global.asax, then that gets compiled at the first request
All ascx and .master files are compiled at the time of a request (by folder) into separate assemblies.
So given the above, you'd have to make requests to at least one page in each folder, to keep the site "hot".
If you've used the "Fixed Names" option then you'll have many more assemblies but this option is also the best for when you want to be able to update the .aspx files. But be sure to test your site and compile performance on the production server.

Take a look at this:
The new "auto start" feature of
ASP.NET 4 and IIS 7.5 provides a
well-defined approach that allows you
to perform expensive application
startup and pre-cache logic that can
run before any end-users hit your
application. This enables you to have
your application "warmed up" and ready
from the very beginning, and deliver a
consistent high performance
experience.
Auto-Start ASP.NET Applications (VS 2010 and .NET 4.0 Series)

Related

Prevent sharing DLL in IIS/ASP.net

lets say I have two ASP MVC applications.
ProjectXXX
ProjectYYY - this is fork of ProjectXXX.
Both projects have same structure (project/assembly name), but it differs on some functionality (it will be deployed for other countries).
For testing purposes we deploy both applications on one server.
ProjectXXX - has own IIS pool
ProjectYYY - has own IIS pool
Problem
When I removed some functionality from assembly of ProjectXXX and run ProjectYYY it throws TypeLoadException : Could not load type 'Project.Namespace.IMyInterface' from assembly 'Project.Namespace'
It looks like ProjectYYY uses DLL from ProjectXXX (IIS (asp.net?) loads dll once, because it "thinks" assemblies are the same?)
How to force IIS not to cache those assemblies and load the proper one for both apps?
EDIT / SOLUTION:
I have found, that my application uses MEF composition. As for now I have changed how it searches for assemblies and problem looks like gone :)
if you create separate IIS Site for each, it should do the trick, as for each site a separate w3wp process is run. Having said that, you can't share same ip and port for 2 sites so if you need that, you'll have to play around with redirecting, url rewriting on IIS.

Can you publish asp.net webforms project keeping it online?

We've quite a big project at work which sometimes needs to be published during the day. However, the application will (of course) crash during publish and show errors. (because the /bin is being overwritten)
Is there a way to avoid this? Sometimes a publish takes up to 3-4 minutes.
I know I can use the app_offline.htm file to display a message instead of them seeing the actual errors.
There isn't a way to have 0 downtime on a deployment. But you have some options
Deploy a pre-compiled site
To speed up the time taken for a site to be active after deployment, you can use ASP.NET Web Site Pre-compilation. This process will package the site so that it will not need to be compiled on-the-fly after deployment.
Benefits
Faster site startup
Less assets to deploy
Can be packaged via the Web Deployment Tool
Drawbacks
Debugging can be harder as the names are scrambled; Debug mode can be turned on for it though
You cannot edit a pre-compiled site; you must do a full re-deployment
You should still use the app_offline.htm so avoid yellow-screen-of-death errors
Add another web server
The best option for these scenarios is to have 2 servers with a load balancer in front of them. Then this way you use the load balancer to redirect active traffic to one node while the new application is being deployed.
Benefits
Parallel deployments do not affect the existing site
Have double the capacity for future expansion
Load balancing allows the load to be spread evenly across servers.
Drawbacks
Session now needs to be stored out-of-process. Therefore, you must check you can switch to an out-of-process session storage to confirm you do not have any serialization problems. StateServer is a quick one to get started with locally.
More maintenance overhead for a deployment, as you need to include load balancing configuration as part of your deployment processes. Network Admins are normally familiar with this.

How to Plugin Web Pages dynamically in ASP .NET (and update the plugin)?

For regular assemblies one can use MEF to load assemblies dynamically. If a live update is required of those assemblies, the recommendation is to use AppDomains to host the dynamic assemblies (potentially one can use Managed Add-in Framework (MAF)). When requiring an update, the appdomain is stopped, the assemblies are updated and the appdomain is reloaded.
What about assemblies that are loaded by ASP .NET that contain that code behind classes? How can I update them without forcing a restart of the main appdomain. Is it possible to host some of my pages in a dynamic appdomain? How would you do that? Can this appdomain share login token and authentication stuff so the user doesn't have to re-login?
Thanks
MEF doesn't support AppDomain isolation, so unfortunately, even during recomposition, those assemblies that had previously been loaded are still loaded in the main web application AppDomain. There are two things you'd need to battle in ASP.NET:
Any changes to physical files (e.g. .aspx, .cshtml, etc), or any changes to configuration files (.config), or any changes to the \bin directory will cause the application to be recycled. This is due to two things, file monitoring of pages/configs, and file monitoring of the \bin directory (which is because by default ASP.NET uses shadow copying of files - this is recommended).
To use MEF in another AppDomain would require a hideous amount of cross-domain communication, either through serialisation or MarshalByRef, which I just don't think would ever be a clean implementation. Not sure how you would trigger BuildProvider instances used to dynamically compile your pages in another AppDomain either.
I'm wondering if you're thinking about this too much. Since IIS6, HTTP.SYS has managed the routing of incoming requests to the appropriate website, this is handled at the kernel level. Even if the main application did restart (which there are a variety of reasons why it could), no requests will be dropped, it would simply queue waiting for a new worker process before passing the request on. Sure, from the user's point of view, they may notice some idle time waiting for the new application to restart, but realistically, how often are you going to be making these changes?
A lot of application design suffers from over-engineering. You may want to design for every scenario, but realistically it is easier to maintain a system which is simple but extensible. In my opinion, wanting to do what you have specified would be classed as over-engineering. Keep it simple.
Using the session "StateServer" will preserve your authentication between app pool recycles (caused by file updates).
For your actual question:
Create a folder outside of your website that your app pool has access to.
Put your new assemblies in there
Have a Task/Thread/Web Service that reads the folder and loads the assemblies into the current App Domain
Assembly.LoadFrom(string) http://msdn.microsoft.com/en-us/library/1009fa28.aspx
The newer version of the assembly should take precedence when an instance is created
I guess your question is saying this method doesn't work? What error are you getting...

How to warm up an ASP.NET MVC application on IIS 7.5?

We would like to warm up an ASP.NET MVC application hosted on IIS 7.5 server. The warm up module that used to be available at http://forums.iis.net/t/1176740.aspx has been removed since sometime.
The application should be warmed up everytime IIS or ASP.NET worker-process restarts for any reason. During the warm up period, IIS should return some HTTP status code signifying its warm up state or its inability to serve any clients.
Would creating a executable that navigates through necessary pages in the site via HttpRequests be a good idea? The executable can be triggered from IProcessHostPreloadClient implementation. Is it possible to configure IIS so that it would only accept requests from localhost and once the executable is done, it can switch over to all clients - but that switch should not trigger an IIS restart (obviously).
Is it possible to use an Visual Studio 2010 - Web Performance Test to warm-up an application instead of creating an manual executable? Any other alternatives?
PS: The application uses Forms Authentication and uses sessions - so maintaining state cookie and other cookies is important.
UPDATE 1 - We are using .NET Framework 4.0 and Entity Framework (database first) in our application. The first time hits to EF queries are slow. The reason behind the warm up is to get these first time hits out of the way. We are already using compiled queries at most places and we have implemented pre-compiled views for EF. The size of the model and application is very large and complex. Warm up needs to walk through many pages to ensure that compiled and non-compiled EF queries get executed at-least once before any end user gets access to the application.
Microsoft has released a module that does exactly what you ask for. The Application Initialization Module for IIS 7.5 improves the responsiveness of Web sites by loading the Web applications before the first request arrives.
You can specify a series of Urls that IIS will preload before accepting requests from real users. I don't think you can get a true user login expereince, but maybe you can set up simulated pages that does not require login that fulfills the same warmup you ask for?
The feature I think is most compelling is that this module also enables overlapped process recycling. The following tutorial from IIS 8.0 include a step-by-step approach on how to enable overlapped process recycling.
When IIS detects that an active worker process is being recycled, IIS does not switch active traffic over to the new recycled worker process until the new worker process finishes running all application initialization Urls in the new process. This ensures that customers browsing your website don't see application initialization pages once an application is live and running.
This IIS Application Initialization module is built into IIS 8.0, but is available for download for IIS 7.5.
You may take a look at the following post for the Auto-Start feature built into IIS 7.5 and ASP.NET 4.0.
Any application that generates a server request for the hosted resources can be used to warm up an IIS process. Exactly how many requests you need depends on what parts need warming up. Typically, warm-up is used for:
Starting up a worker process. For this, you only need to ask for one resource to warm up a process for the entire application.
Perform any static initialization, database startup, or pre-caching. Anything you do in your Global.asax file will happen when you do your first request, so if you can make all of your initialization happen then, you'll still only need to make one page request.
Force pre-compilation of ASP.NET pages. For this to happen you would need to hit every page. Fortunately, this is typically not much of a time cost, so you likely don't need to worry about it. If you do have individual pages that load slowly, you can warm them up separately.
The "warm-up" process here isn't anything magical. You just need force IIS to serve the URL in question. Everything you mentioned would take care of that: using a stress-test tool to query the URL, writing a custom utility to post HTTP requests, even just scripting out a tool like 'wget' or a PowerShell script to download the URLs would do it.
As far as restricting access to localhost, as far as I know, within IIS, the only way to change that requires you to restart IIS. You could always build a pre-request hook into your application and maintain the state there, and have your warm-up process query some specific URL that toggles that state to "open". But I'm not sure what you would accomplish. If, somehow, a user did try to query your site before your warm-up finished, all that would happen is your site would take a long time to respond, then they would eventually get the page they asked for. If you locked them out of the site during warm-up, they would instead get a browser network error that claimed the site was offline, which (to me) sounds much worse.

IIS7 fails to load aspx pages

I've been trying to migrate a fairly large web application from IIS6 to IIS7 the past few days, but every time it seems like we're about done, IIS7 fails to load aspx pages.
The application is a .net 3.5 webapp that makes heavy use of reflection and web services. We use 2 main components (each with their own web site in IIS7 although they share an application pool): the web UI (aspx pages), and the webAPI (asmx pages).
The webAPI portion runs perfectly (as far as we can tell; there are a few things we can't test from the browser), and the web UI pages load static HTM pages just fine. The problem is that once we attempt to view an aspx page (any aspx page), the whole thing just comes to a halt; no error is logged in the event viewer until a few minutes later when we get an IIS 5010 warning (worker process ignoring ping).
We've attempted to migrate the app in two different ways:
Manually: we moved all the necessary files and set up the virtual directories then converted them to Web Sites. Result: the worker process took up 100% of a single core and spun forever (until terminated manually)
Automatically: Utilizing the MSDeploy application from www.iis.net we archived the entire IIS6 web server and unpacked it into a blank IIS7 install. We had to turn off Forms Auth to get rid of a 401.2 error, but after that the result here was that the webAPI component still works just fine, but instead of the web UI worker process taking up 100% of a single core, it grew to about a third of the required memory then hung out doing nothing.
Either way, what happened from the user's point of view was the same.
Unfortunately, we can't even attach a debugger to the worker process because it doesn't seem to be loading managed code.
Details:
.net framework: v3.5
CLR version: v2.0
IIS Authorization mode: Anonymous
OS arch: x64
App arch: x86
Happens with both classic and integrated pipelines
Notes:
New web projects seem to work just fine in IIS7 and, of course, xml web services are also fine
temporary DLLs are created and stored in the temporary ASP.net DLLs folder, even though the worker process never seems to contain managed code.
New pages added to the web UI project also show the same behavior (Didn't hurt to try)
Updates:
We've narrowed down the problem to a single assembly. It's a wrapper for a third party web control. I'm looking into replacing it, we'll see if it fixes the problem.
http://support.softartisans.com/kbview.aspx?ID=1318
Turns out it was an issue with the vendor control. Wish their solution actually worked though...
Try to re-register ASP.NET:
http://msdn.microsoft.com/en-us/library/k6h9cz8h(VS.80).aspx
The typical command line syntax would be to command line to the ASP.NET 2.0 version of your framework and type:
aspnet_regiis -i
Are you using the "Classic" Pipeline Mode for your Application Pool. The "Integrated" one is the default in IIS7 and it introduced changes in terms of configuration. (One example is HttpHandlers that need a different configuration in web.config).
The "Classic" one mimics the IIS6 application pool, and should work with the same configuration as for IIS6.
If you prefer to use the Integrated Pipeline, there are some tools that will automatically try to convert you configuration files.
Scott Hanselman covers some of these tools in his blog post.

Resources