ThreadStatic vs ThreadLocal<T>

Occa­sion­al­ly you might want to make the val­ue of a sta­t­ic or instance field local to a thread (i.e. each thread holds an inde­pen­dent copy of the field), what you need in this case, is a thread-local stor­age.

In C#, there are main­ly two ways to do this.

ThreadStatic

You can mark a field with the Thread­Sta­t­ic attribute:

<br />
[ThreadStatic]<br />
public static int _x;<br />
…<br />
Enumerable.Range(1, 10).Select(i =&gt; new Thread(() =&gt; Console.WriteLine(_x++))).ToList()<br />
          .ForEach(t =&gt; t.Start()); // prints 0 ten times<br />

Whilst this is the eas­i­est way to imple­ment thread-local stor­age in C# it’s impor­tant to under­stand the lim­i­ta­tions here:

  • the Thread­Sta­t­ic attribute doesn’t work with instance fields, it com­piles and runs but does noth­ing..

<br />
[ThreadStatic]<br />
public int _x;<br />
…<br />
Enumerable.Range(1, 10).Select(i =&gt; new Thread(() =&gt; Console.WriteLine(_x++))).ToList()<br />
          .ForEach(t =&gt; t.Start()); // prints 0, 1, 2, … 9<br />
  • field always start with the default val­ue

<br />
[ThreadStatic]<br />
public static int _x = 1;<br />
…<br />
Enumerable.Range(1, 10).Select(i =&gt; new Thread(() =&gt; Console.WriteLine(_x++))).ToList()<br />
          .ForEach(t =&gt; t.Start()); // prints 0 ten times<br />

ThreadLocal<T>

C#  4 has intro­duced a new class specif­i­cal­ly for the thread-local stor­age of data – the ThreadLocal<T> class:

<br />
private readonly ThreadLocal&lt;int&gt; _localX = new ThreadLocal&lt;int&gt;(() =&gt; 1);<br />
…<br />
Enumerable.Range(1, 10).Select(i =&gt; new Thread(() =&gt; Console.WriteLine(_localX++))).ToList()<br />
          .ForEach(t =&gt; t.Start()); // prints 1 ten times<br />

There are some bonus­es to using the ThreadLocal<T> class:

  • val­ues are lazi­ly eval­u­at­ed, the fac­to­ry func­tion eval­u­ates on the first call for each thread
  • you have more con­trol over the ini­tial­iza­tion of the field and is able to ini­tial­ize the field with a non-default val­ue

Summary

As you can see, using ThreadLocal<T> has some clear advan­tages over Thread­Sta­t­ic, though using 4.0 only fea­tures like ThreadLocal<T> means you have to tar­get your project at the .Net 4 frame­work and is there­fore not back­ward com­pat­i­ble with pre­vi­ous ver­sions of the frame­work.

It’s also worth not­ing that besides ThreadLocal<T> and Thread­Sta­t­ic you can also use Thread.GetData and Thread.SetData to fetch and store thread spe­cif­ic data from and to a named Local­Data­S­toreS­lot though this is usu­al­ly cum­ber­some…