views:

33

answers:

2

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 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?

A: 

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 .

Daniel Dyson
+1  A: 

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.

Tiju John
Thanks for your answer. You didn't mention the constructor in your response, though. Why would you need Init() when you can do the same in the constructor with the added benefit of changing private fields to `readonly`?And why isn't `Application_Start` and `Application_End` proper events that can be hooked into with proper event handlers? Plus, will these be called once per worker process, per app domain or what?
asbjornu