.NET 4.5 Baby Steps, Part 1: ThreadLocal

Other posts in this series can be found on the Series Index Page. # Introduction

ThreadLocal<T> was introduced in .NET 4 and didn’t get much attention because it didn’t do much over the ThreadStaticAttribute, which we’ve had since version 1 of the framework. So let’s review what it does. In short, it gives every unique thread that uses it its own global field. Let’s look at this code:

static ThreadLocal<int> balances = new ThreadLocal<int>(() =>
{
    return 10;
});

static void Main(string[] args)
{
    for (int i = 0; i < 10; i++)
    {
        new Thread(AddMoney).Start();
    }

    Console.ReadLine();
}

static void AddMoney()
{
    Console.WriteLine("Before {0}", balances.Value);
    balances.Value += new Random().Next(0, 1000);
    Console.WriteLine("After {0}", balances.Value);
}

Which produces:

Note that every "Before" is set to 10, and that’s because the lambda method that we pass to the ThreadLocal<T> constructor is run for each unique thread.


What’s new in .NET 4.5?

.NET 4.5 improves its usefulness by including the .Values property, which allows you to list the results from each thread. To make use of this, you need to opt in to the feature in the constructor by passing true:

static ThreadLocal<int> balances = new ThreadLocal<int>(() =>
{
    return 10;
}, true);

Then, in my demo, I will output the results using:

foreach (var item in balances.Values)
{
    Console.WriteLine("Balance at end: {0}", item);
}

CropperCapture[2]

CropperCapture[2]

This is very useful when working with threads and performing individual calculations, then collating the results at the end!


Warning

ThreadLocal<T> only works with unique threads. So, if you use it with the TPL or ThreadPool (which reuses threads), it won’t work as expected!

Attachments