Is the static initialization order of this code implementation specific? - c#

I have a design that relies heavily on static initialization. I've noticed that after a series of OS updates, my design appears to be failing on some older versions of the .NET Framework (v<3.5), and only under Release configuration.
I think I've been able to narrow the issue down to a block of code similar in design to this:
public abstract class Foo { public static object A; }
public class Bar : Foo {
public static object B = InitB();
private static object InitB(){ return A }; }
public static void Main()
{
Foo.A = new object();
Bar bar = new Bar();
Console.Write((bar.B==null).ToString());
}
On .NET 2.0, under Release build, on my system, it appears my code is printing true. Whereas on .NET 4.5, it's printing false. Is the behavior of the code above implementation specific?

Your code relies on Bar's static constructor being called after the assignment to Foo.A. The language spec does not guarantee this. It only guarantees it if you actually write a static constructor, not if the compiler implicitly generates one: in that case, it may be called earlier than you expect.
To make sure your code behaves the same way in all valid implementations of .NET Framework, add a static constructor. You don't need to re-factor your initialisers, they can remain where they are.
public class Bar : Foo {
static Bar() { } // <-- add this
public static object B = InitB();
private static object InitB() { return A };
}
Alternatively, re-work your code in such a way that it still works even if the static constructor is called early.

Is the behaviour of the above code implementation specific
For the example above, the docs would suggest that is the case
If a static constructor exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.
For consistency across .NET versions, and to force initialization order, you should add a static constructor to both classes.

Related

Unclear behavior by Garbage Collector while collecting instance properties or fields of reachable object

Till today I was thinking that members of reachable objects are also considered to be reachable.
But, today I found one behavior which creates a problem for us either when Optimize Code is checked or application is executed in Release Mode. It is clear that, release mode comes down to the code optimization as well. So, it seems code optimization is reason for this behavior.
Let's take a look to that code:
public class Demo
{
public Action myDelWithMethod = null;
public Demo()
{
myDelWithMethod = new Action(Method);
// ... Pass it to unmanaged library, which will save that delegate and execute during some lifetime
// Check whether object is alive or not after GC
var reference = new WeakReference(myDelWithMethod, false);
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
Console.WriteLine(reference.IsAlive);
// end - Check whether object is alive or not after GC
}
private void Method() { }
}
I simplified code a bit. Actually, we are using our special delegate, not Action. But the behavior is same. This code is written in mind with "members of reachable objects are also considered to be reachable". But, that delegate will be collected by GC asap. And we have to pass it to some unmanaged library, which will use it for some time.
You can test demo by just adding that line to the Main method:
var p = new Demo();
I can understand the reason of that optimization, but what is the recommended way to prevent such case without creating another function which will use that variable myDelWithMethod which will be called from some place? One, option I found that, it will work if I will set myDelWithMethod in the constructor like so:
myDelWithMethod = () => { };
Then, it won't be collected until owning instance is collected. It seems it can't optimize code in the same way, if lambda expression is setted as a value.
So, will be happy to hear your thoughts. Here are my questions:
Is it right that, members of reachable objects are also considered to
be reachable?
Why it is not collected in case of lambda expression?
Any recommended ways to prevent collection in such cases?
However strange this would sound, JIT is able to treat an object as unreachable even if the object's instance method is being executed - including constructors.
An example would be the following code:
static void Main(string[] args)
{
SomeClass sc = new SomeClass() { Field = new Random().Next() };
sc.DoSomethingElse();
}
class SomeClass
{
public int Field;
public void DoSomethingElse()
{
Console.WriteLine(this.Field.ToString());
// LINE 2: further code, possibly triggering GC
Console.WriteLine("Am I dead?");
}
~SomeClass()
{
Console.WriteLine("Killing...");
}
}
that may print:
615323
Killing...
Am I dead?
This is because of inlining and Eager Root Collection technique - DoSomethingElse method do not use any SomeClass fields, so SomeClass instance is no longer needed after LINE 2.
This happens to code in your constructor. After // ... Pass it to unmanaged library line your Demo instance becomes unreachable, thus its field myDelWithMethod. This answers the first question.
The case of empty lamba expression is different because in such case this lambda is cached in a static field, always reachable:
public class Demo
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Action <>9__1_0;
internal void <.ctor>b__1_0()
{
}
}
public Action myDelWithMethod;
public Demo()
{
myDelWithMethod = (<>c.<>9__1_0 ?? (<>c.<>9__1_0 = new Action(<>c.<>9.<.ctor>b__1_0)));
}
}
Regarding recommended ways in such scenarios, you need to make sure Demo has lifetime long enough to cover all unmanaged code execution. This really depends on your code architecture. You may make Demo static, or use it in a controlled scope related to the unmanaged code scope. It really depends.

static field initialization explanation and its requirement

After looking at so many complicated questions related to this i want to ask the explanation for following code having static field initialization. one more thing i want to know is the requirement of static field initialization. In which scenarios it ll be helpful??
using System;
class Test
{
static void Main()
{
Console.WriteLine("{0} {1}", B.Y, A.X);
}
public static int F(string s)
{
Console.WriteLine(s);
return 1;
}
}
class A
{
static A()
{ }
public static int X = Test.F("Init A");
}
class B
{
static B()
{ }
public static int Y = Test.F("Init B");
}
Output:
Init B
Init A
1 1
When no static constructor is present then output may vary. I am not able to understand the rationale behind it.What difference static field initialization has brought to this fragment?. Can someone please help. I am a newb with c#.
When a type has a static constructor, the runtime is constrained to execute all type initialization immediately before the first use of any member of the type.
When it doesn't have a static constructor, the runtime has much more freedom - it has to execute the type initializer at some point before the first use of a static field or before an instance is constructed, but that's all. You can even observe static methods which don't touch static fields being executed without the type initializer executing.
In your case, both A and B have static constructors, and the order of access to the members is B first, then A, hence your output. Without those static constructors, you'd still be guaranteed to get "1 1" as the last line, and you'd still get both "Init A" and "Init B", but the ordering of them wouldn't be guaranteed.
This is just the way the language and runtime are specified - and usually it has no impact, as usually type initializers should just be setting up the type, with no other side effects. Type initializers should do as little as possible, ideally - if they fail for some reason, the type will never be usable; type initializers aren't retried.
For more details, see my beforefieldinit article and .NET 4.0 type initializer changes blog post.

Do both of these constructors do the same thing?

Do both of these code blocks do the same thing?
class A {
public static int s;
A(){}
static A(){s = 100;}
}
and
class A {
public static int s=100;
A(){}
//static A(){s = 100;} do not use
}
Do they do the same thing? I think so.
No, they don't behave quite the same way. Without the static constructor, the timing of exactly when the type initializer executes is much looser - it can happen earlier or later than you'd expect.
When there's a static constructor, the type initializer executes when the type is first used in terms of any static member being accessed or any instance being created.
When there isn't a static constructor, the only guarantee is that the initializer will be executed at some point before the first access of a static field (and still exactly once). Depending on the JIT, that might mean it's executed very early (e.g. when you first execute a method which might use a member) or very late (after calling static members which don't use any fields, or after creating and using an instance).
In IL, the difference is that a type without a static constructor has the beforefieldinit flag; one with a static constructor doesn't.
The effect is the same, but the actual order of execution may be different. When there is a static constructor, static fields are initialized immediately before the constructor is called or any of the static fields are accessed. If there is no static constructor, then the field initializers can be executed at any time prior to the first usage of one of the static fields.
Since your initializers have no side-effects and cannot throw exceptions, there would not be any discernable difference in the two, barring the use of reflection or some other outside observer (e.g. debugger)
Except for some edge cases such as beforefieldinit behavior, yes, they do the same thing. In fact, the compiled IL is nearly the same in the two cases. The only difference is the presence of beforefieldinit on the one without a static constructor.
class A
{
public static int s;
A() { }
static A() { s = 100; }
}
class B
{
public static int s = 100;
B() { }
}
Compiles to...
.class private auto ansi A
extends [mscorlib]System.Object
.class private auto ansi beforefieldinit B
extends [mscorlib]System.Object
With identical method/field definitions.
According to C# in a Nutshell the static constructor is executed when you first use of the property, and the most usage of this is when you want to calculate or read some data and set to the static property (Like a password from appconfig.config). without using the static constructor you must define a Init method and call it when your application has been started.

In C#, do all static variables get initialized before the main() method is called?

The ones I am particularly concerned about are:
static variables in classes that are defined in referenced/dependency classes, contained in external DLLs. In my example, none of the types in that third party assembly is reference until later in the program. (let's say 5 min into execution).
Will the static variables of that third-party assembly only be loaded then?
Thanks,
rui
according to C# spec which says:
If a static constructor exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class. The example
whiteout a static constructor you can not predict exactly when a static variable is initialized but they are guaranteed to be initialized before their first use. but for sure they are not initialized before you reference their assemblies
All static fields are initialized before they are first used. This can be done by a type initializer (static constructor) explicitly declared or implicitly provided by the compiler. Static fields that do not have a value assigned in the class declaration will be initialized to the default value of their corresponding type.
Be careful if your static fields are object references whose constructors may throw exceptions:
class Foo
{
public Foo() { throw new Exception("boom"); }
}
class Bar
{
private static Foo baz = new Foo();
public Bar()
{
//trying to create a Bar will throw TypeInitializationException
}
public static void BarNone()
{
//trying to call a static method on Bar will throw TypeInitializationException
}
}
You'll get a TypeInitializationException when Bar is first used (either constructed or when a static method on Bar is called), as shown above.

Potential pitfalls with static constructors in C#

My question comes after refactoring a class that contained only static methods to be declared as a static class, and experiencing weird issues when starting the application.
I have not performed any thorough investigation but it seems that some call being made from within the static constructor does not complete for some reason.
So, I would like to know where there are any pitfalls when using static constructors in C#? More specifically, are there any things that should be avoided at all cost and not be used from within the static constructor?
There are several pitfalls to static constructors. For example, if a static constructor throws an exception, you would continue getting a TypeInitializationException whenever you access any of its members.
If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running.
In general, static classes should only be used in stateless scenarios where you won’t need any initialization. If your class needs to be initialized, you might be better off using the singleton pattern, which can be lazily initialized on first access:
public class MyClass
{
private static readonly Lazy<MyClass> current =
new Lazy<MyClass>(() => new MyClass());
public static MyClass Current
{
get { return current.Value; }
}
private MyClass()
{
// Initialization goes here.
}
public void Foo()
{
// ...
}
public void Bar()
{
// ...
}
}
static void Main(string[] args)
{
MyClass.Current.Foo(); // Initialization only performed here.
MyClass.Current.Bar();
MyClass.Current.Foo();
}
Edit: I did some further reading up on the matter, and it appears that static constructors do cause deadlocks if you perform blocking operations (e.g. asynchronous callbacks or thread synchronization) within them.
The CLR internally uses locking to prevent type initializers (static constructors) from being executed multiple times concurrently. Thus, if your static constructor attempts to access another member of its declaring type from another thread, it would inevitably deadlock. Since “another member” could be an anonymous function declared as part of a PLINQ or TPL operation, these bugs can be subtle and hard to identify.
Igor Ostrovsky (MSFT) explains this in his Static constructor deadlocks article, providing the following example of a deadlock:
using System.Threading;
class MyClass
{
static void Main() { /* Won’t run... the static constructor deadlocks */ }
static MyClass()
{
Thread thread = new Thread(arg => { });
thread.Start();
thread.Join();
}
}
In the above example, the new thread needs to access the empty anonymous function, { }, defined as its callback. However, since the anonymous function is compiled as another private method of MyClass behind the scenes, the new thread cannot access it before the MyClass type initializes. And, since the MyClass static constructor needs to wait for the new thread to complete first (because of thread.Join()), a deadlock ensues.
Yes, there are some pitfalls, mostly related to when the class is initialized. Basically, a class with a static constructor will not be marked with the beforefieldinit flag, which allows the runtime to initialize it at a later time.
Have a look at this article for more details.
This is not an answer to the question, but it's too long for a comment, so I offer it here...
Since I didn't know for static class construct, I have used following scheme (simplified) to provide me with singletons:
public class SomeSingleton {
static _instance;
static public SomeSingleton Instance {
get {
if (_instance==null) {
_instance=new SomeSingleton();
}
return _instance;
}
}
}
Later, you use
SomeSingleton.Instance.MyProp = 3;
And first usage of the Instance member will construct your singleton.
I guess that it is OK since instantiation of the singletons if there are many of such classes is done in proper order.

Categories

Resources