Why is HttpApplication constructor called several times - asp.net

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).

Related

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 .

Ihttpmodule ,Ihttphandler .NET

I have some doubt over HttpModule and HttpHandler Please help me to clarify
1)In HttpModule I have noticed methods Init called only once . context_BeginRequest and context_EndRequest etc method calling for each request.
Is it guaranteed that for a module Init will call once for different users(or different request) and BeginRequest etc will call every time for different users (or different request) ?
2)Is there any possibility that Application_Start(global.asax) can run more than once because there may be more than one application object
3) Since application object can be different (from application pool) In this case how Application data is shared between different users?
4) In HttpHandler ProcessRequest method will call for each request (or for each user).
Thanks
Ritu
"Is it guaranteed that for a module Init will call once for different users(or different request) and BeginRequest etc will call every time for different users (or different request)?"
The init method will be called when the app pool starts / when the application is started for the first time. This is when the module is loaded.
The BeginRequest method is called every time the application starts handling a new HTTP request.
"2)Is there any possibility that Application_Start(global.asax) can run more than once because there may be more than one application object"
There is not more than one application in a particular folder. IIS doesn't work that way. Only one global.asax per application, and Application_Start will only be called once for each application unless the app pool is reset.
"3) Since application object can be different (from application pool) In this case how Application data is shared between different users?"
Depends where you're storing this application data and what you're using to retrieve it. I'm not sure what you mean about this. Session data should be scoped to an individual application (certainly for in-process session state server, and if properly configured also for out-of-process session state server)
"4) In HttpHandler ProcessRequest method will call for each request (or for each user)."
Yes, but only for requests which are mapped to your handler. Conversely, HttpModule can be called for ALL requests.

Does Application_Start block all incoming requests

I have some code that initializes a static singleton class, which is needed by all requests. Therefore I thought I could add it to global.asax Application_Start. Can I be 100% sure that all requests will block while Application_Start is loading to guarantee that all the requests will have access to it?
Thanks a lot
Jeeji
Short answer: yes.
Application_Start:
Called when the first resource (such
as a page) in an ASP.NET application
is requested. The Application_Start
method is called only one time during
the life cycle of an application. You
can use this method to perform startup
tasks such as loading data into the
cache and initializing static values.
You should set only static data during
application start. Do not set any
instance data because it will be
available only to the first instance
of the HttpApplication class that is
created.
http://msdn.microsoft.com/en-us/library/ms178473.aspx

Shared/Static variable in Global.asax isolated per request?

I have some ASP.NET web services which all share a common helper class they only need to instantiate one instance of per server. It's used for simple translation of data, but does spend some time during start-up loading things from the web.config file, etc. The helper class is 100% thread-safe. Think of it as a simple library of utility calls. I'd make all the methods shared on the class, but I want to load the initial configuration from web.config. We've deployed the web services to IIS 6.0 and using an Application Pool, with a Web Garden of 15 workers.
I declared the helper class as a Private Shared variable in Global.asax, and added a lazy load Shared ReadOnly property like this:
Private Shared _helper As MyHelperClass
Public Shared ReadOnly Property Helper() As MyHelperClass
Get
If _helper Is Nothing Then
_helper = New MyHelperClass()
End If
Return _helper
End Get
End Property
I have logging code in the constructor for MyHelperClass(), and it shows the constructor running for each request, even on the same thread. I'm sure I'm just missing some key detail of ASP.NET but MSDN hasn't been very helpful.
I've tried doing similar things using both Application("Helper") and Cache("Helper") and I still saw the constructor run with each request.
You can place your Helper in the Application State. Do this in global.asax:
void Application_Start(object sender, EventArgs e)
{
Application.Add("MyHelper", new MyHelperClass());
}
You can use the Helper that way:
MyHelperClass helper = (MyHelperClass)HttpContext.Current.Application["MyHelper"];
helper.Foo();
This results in a single instance of the MyHelperClass class that is created on application start and lives in application state. Since the instance is created in Application_Start, this happens only once for each HttpApplication instance and not per Request.
It's not wise to use application state unless you absolutely require it, things are much simpler if you stick to using per-request objects. Any addition of state to the helper classes could cause all sorts of subtle errors. Use the HttpContext.Current items collection and intialise it per request. A VB module would do what you want, but you must be sure not to make it stateful.
I 'v done something like this in my own app in the past and it caused all kinds of weird errors.
Every user will have access to everyone else's data in the property. Plus you could end up with one user being in the middle of using it and than getting cut off because its being requested by another user.
No there not isolated.

Resources