A method in a class in an assembly decorated by PreApplicationStartMethod
attribute is meant to be called before Application_Start
event is fired.
For example, this is how BuildManager
gets to know what assemblies (in addition to ones in the web application) to reference when compiling a page, a control, or a view.
It is quite natural to expect the pointed out method to be called only once -- after all it it part of an initialization process, which normally occurs only once per application. (I will only mention an attempt to create a database twice!!)
After adding some trace calls I discovered that the method (not always, sometimes!) is called twice.
In order to avoid this I added a boolean field to the class to prevent multiple calls like this:
private static bool initialzed;
public static void Initialize()
if (PreApplicationInit.initialzed == false)
{
// perform the initialization here
// ...
PreApplicationInit.initialzed = true;
}
}
To my surprise the method got called twice again. An obvious suspicion was that it is called on two different threads (despite this makes a little sense in an initialization code). Double-check locking was an obvious solution to such a problem, so I changed the code like this:
private static readonly object SyncRoot = new Object();
private static bool initialzed;
public static void Initialize()
{
if (PreApplicationInit.initialzed == false)
{
lock (PreApplicationInit.SyncRoot)
{
if (PreApplicationInit.initialzed == false)
{
// perform the initialization here
// ...
PreApplicationInit.initialzed = true;
}
}
}
}
What is really making this an issue is the fact that the code is called from native code. Tthis is the $CALLER from a tracepoint:
[Native to Managed Transition]
So, my question is obvious, I guess: what (and more important why!) invokes a method denoted to be called before Application_Start
event more than once?