Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a readonly static field be null?

So here's an excerpt from one of my classes:

    [ThreadStatic]     readonly static private AccountManager _instance = new AccountManager();      private AccountManager()     {     }      static public AccountManager Instance     {         get { return _instance; }     } 

As you can see, it's a singleton-per-thread - i.e. the instance is marked with the ThreadStatic attribute. The instance is also instantiated as part of static construction.

So that being the case, how is it possible that I'm getting a NullReferenceException in my ASP.NET MVC application when I try to use the Instance property?

like image 373
gerrod Avatar asked Jan 11 '10 17:01

gerrod


People also ask

What does readonly do in c#?

Use the readonly keyword in C# The readonly keyword can be used to define a variable or an object as readable only. This means that the variable or object can be assigned a value at the class scope or in a constructor only.

Is static readonly thread safe?

Only the initialization of static fields are thread safe, the value is not! To guarantee thread safety on static fields, add readonly (read initonly). This guarantees that the value cannot be overwritten (if you are not using a collection of some sort that is).

How to make a variable read only in c#?

In C#, you can use a readonly keyword to declare a readonly variable. This readonly keyword shows that you can assign the variable only when you declare a variable or in a constructor of the same class in which it is declared.

What is private static readonly in C#?

A Static Readonly type variable's value can be assigned at runtime or assigned at compile time and changed at runtime. But this variable's value can only be changed in the static constructor. And cannot be changed further. It can change only once at runtime.


2 Answers

Quoting MSDN ThreadStaticAttribute:

Do not specify initial values for fields marked with ThreadStaticAttribute, because such initialization occurs only once, when the class constructor executes, and therefore affects only one thread. If you do not specify an initial value, you can rely on the field being initialized to its default value if it is a value type, or to a null reference (Nothing in Visual Basic) if it is a reference type.

like image 67
Austin Salonen Avatar answered Oct 22 '22 22:10

Austin Salonen


This is a confusing part of the ThreadStatic attribute. Even though it creates a value per thread, the initalization code is only run on one of the threads. All of the other threads which access this value will get the default for that type instead of the result of the initialization code.

Instead of value initialization, wrap it in a property that does the initialization for you.

[ThreadStatic] readonly static private AccountManager _instance;  private AccountManager() { }  static public AccountManager Instance {   get    {      if ( _instance == null ) _instance = new AccountManager();     return _instance;    } } 

Because the value _instance is unique per thread, no locking is necessary in the property and it can be treated like any other lazily initialized value.

like image 33
JaredPar Avatar answered Oct 22 '22 22:10

JaredPar