ASP.NET Application lifecycle - Application_Start - asp.net

Having a read of the application lifecycle in IIS 7.0, on msdn and confused by the following line about halfway down , "The first time that an ASP.NET page or process is requested in an application, a new instance of the HttpApplication class is created. However, to maximize performance, HttpApplication instances might be reused for multiple requests.". That would suggest that discounting performance, the majority of the time a new instance of the HttpApplication class is created per request.
If that is correct, that would mean Application_Start firing on each request. I only ever thought it fired once when the appdomain is started

Related

First Web API request triggers execution of Application_Start

I'm having a Web application that also integrates a Web API. Just today I've found myself surprised to see that the first REST request on the Web API re-triggers the execution of Application_Start (although it has been run already when starting the web page). After reading ASP.NET HttpApplication lifecycle and ASP.NET Application Life Cycle Overview, it seems that the REST request is spawning a new HttpApplication.
Further, on the MSDN it says:
The first time that an ASP.NET page or process is requested in an application, a new instance of the HttpApplication class is created. However, to maximize performance, HttpApplication instances might be reused for multiple requests.
This sounds to me that each request could potentially spawn a new HttpApplication and that thus, Application_Start must be written in a re-entrant or idempotent way. Is this conclusion right?
In my concrete case, I'm initializing a log writer in Application_Start which fails the second time because the file is already being used. I guess in the case of an application pool recycling this wouldn't be a problem, as the resources are freed in-between.
You can read further down on the provided link
The Application_Start and Application_End methods are special methods that do not represent HttpApplication events. ASP.NET calls them once for the lifetime of the application domain, not for each HttpApplication instance.
So there is no need to write Application_Start in a re-entrant or idempotent way.
Furthermore Application_Start is not called on the recycling of IIS. It gets called on the first request after recycling when the application is actually loaded by IIS.
As for your error, make sure you're disposing off your logger on Application_End so the file handle gets released.

Will Application_End be fired even if …

Application_Start and Application_End are called only once during the lifetime of the application domain – thus they aren’t called for each HttpApplication instance
Application_Start runs when first user requests a page, thus when the first instance of the HttpApplication class is created, while Application_End runs when the last instance of an HttpApplication class is destroyed.
But what if at the time of application domain being restarted there wasn’t any user requests and thus no HttpApplication instances created? Will in that case Application_End still be fired?
Thank you
If I understand your question correctly, you're saying that no requests ever came, if no requests ever come in the application will never be started (i.e. no Application_Start is fired) and therefore no the Application_end wouldn't fire either.
This is not withstanding any kind of "pre-warming" code which fires up the application before requests are received in order to load up caches or things like that.

Advanced: How many times does HttpModule Init() method get called during application's life?

Web application initialization is as follows:
As we know when IIS receives the first request for a particular Asp.net application resource, IIS creates an instance of a HttpApplication (defined in global.asax codebehind).
When this new instance is created it's initialization happens that also checks all configured HTTP modules.
All modules are then instantiated and put in the application's Modules collection (of type HttpModuleCollection)
modules are looped through and their Init() method is called (when they register for request events)
As far as I understand it the above scenario happens when a web application is started/initialized (hence application start event).
What happens with modules?
Are they (re)instatiated on each request or reused from the Modules property on each consecutive request while the web application is alive? As I understand IIS and Asp.net they are reused through the whole life of a web application.
If they are reused, can we assume that their Init() method is actually a pseudo event handler for application start event? The thing is we can't attach to application level events within http modules. But if they are being reused we could use Init() as application start event and do whatever we'd put in global.asax instead.
Question
Can we assume that module's Init() method is called only on application start event? Could we use this assumption to i.e. register routes for applications whose global.asax codebehind we can't change? web.config is usually accessible and we can change it the way we want.
Would this actually work?
Additional info
We can check HttpApplication code and check its InitModulesCommon() method. This one actually calls Init() of each registered HTTP module. What is more interesting is that this method is only used by InitIntegratedModules() and InitModules() methods. Which are both used only in HttpApplication.InitInternal() method. This is the basis of my assumptions, but I would like to know whether someone has abused IHttpModule.Init() for application start event.
Init() is called only once (per HttpApplication instance)
After I tested this the inner workings of IHttpModule initialization are as follows:
Every IHttpModule is initialized at web application start by instatiating and a call to Init() method
HttpApplication stores all module instances in its Modules property
Modules are then reused for the whole life of an HttpApplication and are not discarded/reinitialized as long as the application is alive
So the best outcome is
You can't attach an IHttpModule to application level events, but you can use its Init() method as pseudo application start event delegate. Inside it you can execute any code that you'd usually put inside Application_Start delegate in your Global.asax.
You can also read detailed information about it in my blog post.
But be careful in real-life web server environment
But IIS uses something called application pools. And each pool can have an arbitrary number of HttpApplication instances. Yes multiple. Application starting creates all these instances. Every one of them initializes their own list of modules but only the first one executes the Application_OnStart event handler.
So whenever your module modifies some common shared resource, you should take extra measures to indicate that the first module has done that and others won't do it again. Read an additional blog post about it that will show you how and when to use thread locking with your module to make it actually act as an Application_OnStart event handler. BTW: It's also possible to handle Application_OnEnd event if you need to. ;)
Detailed blog post links
Writing a custom IHttpModule that handles Application_OnStart event
How to correctly use IHttpModule to handle Application_OnStart event
Application_Start is only run once for the lifetime of your application.
IHttpModule.Init is run for each instance of HttpApplication, before request processing begins. See the walkthrough. Init is where you can register events used to process the request.
An instance of HttpApplication can be reused for multiple requests. ASP.Net pools HttpApplication objects, so the Init will be called once for every new instance of HttpApplication

Application_Start versus OnInit versus constructor

I've gone rounds with this ever since I started programming classic ASP 12 (or so) years ago and I've never found a great solution because the architecture of ASP and ASP.NET has always been a swamp of bad practices, magic shared singletons, etc. My biggest issue is with the HttpApplication object with its non-event events (Application_Start, Application_End, etc.).
If you want to do stuff once for the entire lifespan of an HTTP application, Application_Start is the obvious place to do it. Right? Not exactly. Firstly, this is not an event per se, it's a magic naming convention that, when followed, causes the method to be called once per AppDomain created by IIS.
Besides magic naming conventions being a horrible practice, I've started to think it might be a reason there exist no such thing as a Start event on the HttpApplication object. So I've experimented with events that do exist, such as Init. Well, this isn't really an event either, it's an overridable method, which is the next best thing.
It seems that the Init() method is called for every instantiation of an HttpApplication object, which happens a lot more than once per AppDomain. This means that I might as well just put my startup logic inside the HttpApplication object's constructor.
Now my question is, why shouldn't I put my startup logic in the constructor? Why does even Init() exist and do I need to care about Application_Start? If I do, can anyone explain why there is no proper event or overridable method for this pseudo-event in the HttpApplication object?
And can anyone explain to me why in a typical ASP.NET application, 8 instances of my HttpApplication are created (which causes the constructor and Init to run just as many times, of course; this can be mitigated with locking and a shared static boolean called initialized) when my application only has a single AppDomain?
The Asp.Net runtime keeps a pool of HttpApplication objects. Every .aspx request is processed by a single object which is allocated from the pool(8 objects in your case).
The answer to your question, Application_Start event is indeed called, but only for the first instance of the HttpApplication, not subsequent ones, so you can be sure that it is called exactly once whenever your application is started or the application pool of IIS is restarted. So is Application_OnEnd event (last instance)
meanwhile, the Init() and Dispose() are called on every instance of the HttpApplication object. That will be called on each instance a.k.a. each request.
Why do they do it that way..? maybe to balance performance and memory optimizations.
Hope i answered your question.
Calling Application_Start the first time an instance of HttpApplication is created, but not on subsequent instances seems a bit of a hack. Perhaps Microsoft didn't want to explain the concept of a static constructor to people who didn't really want to know.
Application_End(), however, seems to be a necessity, as there is no C# equivalent of a static destructor/finalizer. As hacks go, this isn't that bad. It just smells a little funny.
There is one HttpApplication object created for each concurrent request. That is each thread that ASP.NET creates gets its own instance of HttpApplication. Instances are re-used for subsequent requests in the same way that threads are re-used from the thread pool.
Use the Init method to initialize instance fields on the HttpApplication as these will only be initialized one the first instance if it is done in the Application_Start event .

Why is HttpApplication constructor called several times

Can somebody explain why the constructor of a custom class derived from HttpApplication is called several times upon application startup?
My code structure is the following:
- My Global class in global.asax derives from CustomApp class.
- The CustomApp class derives from HttpApplication class
The Global class is created at startup, but when I place a breakpoint in the constructor, it is invoked several times! I thought there should be only one instance of Application class created?
Am I wrong?
UPD: the web server can indeed create several HttpApplication instances to process multiple requests coming in at the same time. This becomes especially apparent when you place a breakpoint in the constructor of your HttpApplication descendant. Several requests will be pending from the client (http content, CSS files, etc) and to serve each of them the web server will create new instances of HttpApp. So, beware of this, when writing the application initialization logic.
I believe the ASP.NET runtime may create more than one HttpApplication per application domain. So HttpApplication.Init and the Ctor may get called more than once.
If you want to have initialization code that only runs once, you should use the Application_Start event which will only be called once per app.
Please have a look at a post global.asax in ASP.NET - it explains why there are multiple instances of the HttpApplication. Basically there are two pools: special and normal. Normal pool contains instances of the HttpApplication which are used by the requests (each requests has its own HttpApplication instance). Special pool contains HttpApplication objects used for application-level events (like Application_Start, Application_Error).

Resources