When does an ASP.NET Website project recompile? - asp.net

As Maurico and codeka first stated, don't use the default InProc sessions if you don't want your sessions to be affected by website recompiles and application recycles.
A list of what causes whole website recompile:
By default, when any change is made to a top-level file in a Web site, the whole site is recompiled. Top-level files include the global.asax file and all files in the bin/ and App_Code/ folders.
modifying web.config
a configuration include file change, if the SectionInformation.RestartOnExternalChanges property is true
<section
name="MyAppSettings"
type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
restartOnExternalChanges="true"
requirePermission="false" />
Notes:
If you want to be able to change top-level files without causing the whole site to be recompiled, you can set the optimizeCompilations attribute of the compilation element in the Web.config file to true
References:
Understanding ASP.NET Dynamic Compilation
Where's the info that tells the kinds of changes and files which cause a website project (not web application project) to recompile itself?
The reason I'm asking is because we don't want users to lose their sessions. Therefore we want to update the live website with recompilable changes only in the very wee hours of the morning, but would prefer to make changes during the day to expedite them. We do promote to a staging server first and watch it there, but a definitive list would be nice in advance.

You'll lose sessions not just when your website is recompiled, but also when the IIS worker process is recycled. Technically, that can happen at any time (there are ways to minimise it, but I prefer to architect applications that can survive worker process recycles anyway), so if sessions are important then you really do need to be storing them out-of-process.
ASP.NET comes with a built-in "state server" which is just a windows service that stores session state. Another option is to use the SQL Server session state storage.
A lot of people will tell you that storing session state in SQL Server is a performance problem, but I disagree: losing sessions due to process recycles is more of a concern than the performance of SQL Server. Besidess the ASP.NET state server is faster if that's what you really need (and if you want to survive power cycles you could even write a custom provider that stores state in a NoSQL database!)

Related

Double App Domains in ASP.NET 4 application

I've got an ASP.NET application running on IIS 7 with multiple application domains, and I can't fathom why there are multiple app domains in a single process. I've grepped my code base, and I'm not explicitly creating a second application domain. Is it possible that a recycle has failed to time out?
These double domains will persist for sometime.
If a recycle occurs because of a web config or binary change, both app domains will go down, and two new ones will start up.
These servers are subject to several binary patches and IISResets per day - sometimes there are 2 domains, sometimes only 1.
Web gardening is disabled.
I discovered this because there is a timer in the application heart-beating to the database, and noticed one day the server had two heartbeats.
In windbg, !dumpdomain shows me the following result: (filtered to only show names of app domains):
Line 59: Name: None
Line 66: Name: None
Line 372: Name: DefaultDomain
Line 460: Name: /LM/W3SVC/1/ROOT/MyAppDomain-1-129882892717131250
Line 4437: Name: /LM/W3SVC/1/ROOT/MyAppDomain-4-129285605131450579
Even though you aren't creating an AppDomain, a library that you are using might be. What third-party components are you using? Do you have any Inversion of Control or Dynamic Proxy libraries that might be responsible? Here's an explanation of this happening with Castle.
Are you sure the application is only running in one place in IIS? It's possible to have multiple IIS sites/applications running off of the same files. This would be consistent with (1) getting your debug info from the db, rather than the app, and (2) the recycle due to editing web.config consistently resulting in duplicate domains. If one location is more commonly accessed than the other this could explain why there is sometimes only one AppDomain.
If you are leveraging ASP.NET's dynamic compilation and shadow copying feature, ASP.NET will at times have multiple AppDomains. Jim Schubert wrote an article called ASP.NET, AppDomains, and shadow-copying which explains this in more detail as well as makes several suggestions as to how to modify web.config to customize this. He also has a helpful answer over at Does my ASP.NET application stop executing if I overwrite the DLLs? Shadow copying can be disabled by setting <hostingEnvironment shadowCopyBinAssemblies="false" />.
Update
I got sucked into Jim Schubert's blog and ended up reading this unrelated post on Allowing Only A Single Instance of a .NET application. If all else fails, you could use this approach to ensure only one instance of the application is running.
May have a look at your ApplicationHost.config.
have a look at: maxProcesses it should be 1.
It seems your IIS starts multiple worker-processes.
As suggested by the following answer https://stackoverflow.com/a/3318367/2001769
in another thread, it seems the ASP.NET runtime keeps a pool of HttpApplication instances (irrespective of maxProcesses / Web Garden).
I don't know if is possible, or even desirable, to control this pool. The best practice could be to instantiate all application singletons in the Application_Start event that is supposed to run only once per application and not once per pooled HttpApplication instance.
If there are multiple IIS Applications targeting the same path. An AppDomain will be created per such IIS Application if the app is invoked.
For example:
http://myServer/App1
http://myServer/App2
If both target the same path they still count as two different applications and two AppDomains will be created.

application pool memory usage monitor

I have a website in IIS 7 and I need to monitor the memory usage of that website when there are concurrent requests for it. Can you please let me know how can i do this? Is there any tool available or is that possible to use any feature of IIS?
Windows Performance Monitor should be able to get you pretty close to what you want. There are literally hundreds of metrics in there to use.
To access it, simply do Start -> Run -> perfmon
From there, select 'Performance Monitor' in the left pane, and click the '+' button to begin adding in counters.
If its an ASP.NET based web site, you can select one of the 'ASP.NET Apps' counter categories (may have more than 1 if you have more than 1 version of ASP.NET installed) and click on the 'Managed Memory Used' counter. In the list below that, all actibe websites are displayed and you can add the counter for that. You can watch the counter in realtime or elect to save the data to disk or a DB for later analysis.
There is a W3SVC_W3WP counter category that allows you to examine metrics for specific app pools but nothing (that I can see) that will offer memory used per app pool.
Depending on what you are trying to determine though, you may be able to find a bunch of metrics to aid in your analysis.
To get the 'Managed Memory Used' counter to work on my server I found I had to make an additional change:
The aspnet.config config file (generally located at C:\Windows\Microsoft.NET\Framework\v4.0.30319, YMMV) needs to be modified to include the appDomainResourceMonitoring element (although there will probably be other stuff there as well):
<configuration>
<runtime>
<appDomainResourceMonitoring enabled="true"/>
</runtime>
</configuration>
There is no need to restart IIS, but you do need to recycle application pool you want to monitor.
See these two blog posts for more info:
Performance Monitoring of individual Asp.net Application in Asp.net 4.0
Asp.Net 4.0: An Overview-Part-III

Manually refresh output cache in IIS7

Problem description:
On our website we use standard asp cache with duration set to 5h.
It works fine, but sometimes the publisher add some special content that need to be showed impatiently on many different sub-pages (example some promoted article).
That's what I need to do it's easy to use page like this:
mydomain.com/admin/clear-all-website-output-cache.aspx.
I want to clear SERVER SIDE CACHE.
Thanks for help.
we use: IIS7, ASP.net 3.5
See this ServerFault question: Will an IIS reset force cached items to be resent?
This says that you need to use IISRESET (or reset IIS any other way) to do it.
I assume recycling the application pool of the application will have the same effect. It's a good practice to have one application pool per application, so, this should be less problematic than resetting IIS if there are other critical applications.
If your app pool is shared with other applications, create a new one, and change the app pool in the application properties to the new pool. Likely will have a similar effect.
BTW, I do not think stopping and starting the website (assuming likely the app has its own website) will have a similar effect, as it will not stop the process instance that holds the cache, which is represented by app pool. Not 100% sure though.
Use cache dependency on some file, the cache will expire when the file changed.

How do I force ASP.Net to invalid (and thus reload) the current application instance?

Basically I want the effect that would occur if I were to edit the web.config file. The application basically completely unloads itself and starts again, thus re-firing Application_Start and also ditching any dynamically created Types created by the now-defunct AppDomain.
EDIT
I need to do this in my C# code inside my web application. I know it can be done; I did it ages ago but have since lost the code and forgotten how I did it.
For full trust you can use HttpRuntime.UnloadAppDomain(). If you aren't running in full trust you can modify the last write time on the web.config file. Rick Strahl has wrapped these two approaches up in a nice class.
You can "touch" the web.config file (i.e. rewrite it to disk unchanged), or any file in the bin directory to recycle the application. Of course this means the identity under which your application is running needs appropriate permissions.
Lately I seem to be answering my own questions a lot :P
Here we go:
HttpRuntime.UnloadAppDomain();
If all the options above fail, you can also create an endless recursive function as a final resort. The resulting stackoverflow exception will force a reload of the application. (don't do this when you have the visual studio debugger attached)
In IIS you can recycle the worker processes. You don't need to restart IIS.
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/24e3c22e-79a9-4f07-a407-dbd0e7f35432.mspx?mfr=true
If you have created a separate application pool for your application, you can reset the Application Pool.
In general, it's always a good idea to have separate app pool's for each application.

How to update ASP.Net site dll without stopping site

Is it possible to update the site dll for a precompiled site without stopping IIS.
Currently, if I try to just copy the new file to overwrite the current file, All users receive runtime errors while the file is being copied. Is there a way to avoid this?
even if you don't stop, any change to the web.config file, BIN folder, App_Data or App_Code will force the .NET compiler to perform ...
and you will loose any Session variables in memory.
What I do is to use Session State in SQL Mode and if your system is set up like this, user will remain in the site (after a longer exposition to a page reload)
.NET will still invoke the compiler in order to compile the new set of instructions but soon it is done, all sessions will be read from SQL Server and because they are still there (and not lost with a memory refresh) users will remain in the website with current credentials.
it is a little bit slower than In-Memory Session State, but much more reliable, specially with Shared hosting :) this is the way to increse/decrese the minutes in your session, as Shared hosting do not allow it to change even if you do
Session.Timeout = 5;
their machine configuration will override everything you do, with SQL Session State, you will be able to set your time as this is all made by SQL Server.
Fell free to read this article to know how everything is done.
Hope it helps.

Resources