The static field initializer starts before Application_start, sometimes

I have an ASP.NET web application that is starting to show very strange behavior. Here is a sample code:

// in Bar.cs public class Bar { public static Baz baz = Something.Step2(); } // in Global.asax public void Application_Start(...) { Something.Step1(); } 

The short version of the story is this: on some machines, Something.Step2 runs before Something.Step1 and throws an inexplicable exception. On other machines, Step1 is correctly executed before stage 2. Global.asax and all objects that it uses do not belong to Bar at all.

When should static fields be implemented in relation to other programming elements? Why do two machines (both Win7 64-bit and .NET 4.0, the same version of IIS, etc.) do things on different orders? The order is also agreed on each machine. On my machine, he always runs Step2 to Step1, but on my machine, the co-author always runs Step1 to Step2.

Help really appreciate.

Update . I found the reason why my static field is being accessed. The Bar class from my example is actually a custom authentication module and is referred to in web.config as the authentication handler in System.webServer. If I remove this line from web.config, my system will call Step1 first and never call Step2 at all. My question subtly changes: "Why does web.config cause my static initializers to start and why does it start them before running Application_Start?"

+4
source share
1 answer

Static field initializers, if you do not have a static constructor, are initialized in an "implementation-dependent" time until the first access. This means that they can be initialized at any time - you cannot rely on Bar.Baz initializing for the first time you use Bar .

Adding a static constructor to Bar will change the behavior of this object to a greater extent than you expect.

See the C # language specification, section 10.5.5.1 for more details:

10.5.5.1 Initialization of a static field

The initializers of a static variable of a class field correspond to a sequence of assignments that are executed in the textual order in which they appear in the class declaration. If a static constructor exists in the class (Β§ 10.12), the execution of the initializers of the static field occurs immediately before the execution of this static constructor. Otherwise, the static field initializers are executed at the implementation-dependent time until the first use of the static field of this class.

In addition, see 10.2 for details on static constructors:

A static constructor for a closed class type is executed no more than once in a given application domain. The execution of the static constructor is triggered by the first of the following events in the application domain:

. An instance of the class type is created.

. A reference to any of the static members of a class type.

At the same time, if deterministic initialization is required, I strongly recommend adding a static constructor to Something and doing the correct initialization there. In addition to providing a guarantee of the initialization order in this case, this will prevent Something from being used by another class, causing your code to break in the future.

+6
source

All Articles