Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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.

You've hit a classic [ThreadStatic] "101" here.

The static initializer will only fire once, even though it is marked as [ThreadStatic], so other threads (apart from the first) will see this uninitialised.

I believe what is happening is that the static field is only being initialized once so when another thread tries to read the field it will be null (since its the default value) because _instance can't be initialized again. Its just a thought but and I could be totally way off but that's what I think is happening.

A static field marked with ThreadStaticAttribute is not shared between threads. Each executing thread has a separate instance of the field, and independently sets and gets values for that field. If the field is accessed on a different thread, it will contain a different value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top