Skip to content

Initializing ThreadStatic fields

Yesterday a friend of mine came across a problem concerning the initialization of ThreadStatic fields. He always encountered a NullReferenceException while accessing those fields.

Here's a sketch of what he tried to do:

C#:
  1. class Program
  2. {
  3.     [ThreadStatic]
  4.     static StringBuilder aValue = new StringBuilder();
  5.  
  6.     static void Main(string[] args)
  7.     {
  8.         Program p = new Program();
  9.         ThreadStart ts = new ThreadStart(p.RunThread);
  10.         Thread t1 = new Thread(ts);
  11.         Thread t2 = new Thread(ts);
  12.         t1.Start();
  13.         t2.Start();
  14.     }
  15.  
  16.     void RunThread()
  17.     {
  18.         Console.WriteLine(Program.aValue.ToString());
  19.     }
  20.  
  21. }

Everytime the program executed RunThread() the NullReferenceException has been raised. Therefore the question was why the field aValue didn't get initialized.

As usally a note at .Net Framework Reference has an answer to this question:

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.

So, next question: How to initialize ThreadStatic fields?

We decided to encapsulate the initialization in a property:

C#:
  1. class Program
  2. {
  3.     [ThreadStatic]
  4.     static StringBuilder aValue;
  5.  
  6.     static StringBuilder AValue
  7.     {
  8.         get
  9.         {
  10.             if (null == aValue)
  11.                 aValue = new StringBuilder();
  12.             return aValue;
  13.         }
  14.     }
  15.  
  16.     static void Main(string[] args)
  17.     {
  18.         Program p = new Program();
  19.         ThreadStart ts = new ThreadStart(p.RunThread);
  20.         Thread t1 = new Thread(ts);
  21.         Thread t2 = new Thread(ts);
  22.         t1.Start();
  23.         t2.Start();
  24.     }
  25.  
  26.     void RunThread()
  27.     {
  28.         Console.WriteLine(Program.AValue.ToString());
  29.     }
  30.  
  31. }

Categories: Programming.

Tags: , , ,

Comment Feed

No Responses (yet)



Some HTML is OK

or, reply to this post via trackback.