ThreadLocal<T> Class

System.Threading

Represents thread-local storage that provides lazy initialization of data that is local to a thread.

Syntax

public sealed class ThreadLocal<T> : IDisposable

Type Parameters

T
The type of the value stored in the thread-local storage.

Constructors

Properties

Methods

Remarks

The ThreadLocal<T> class is used to create thread-local data. This means that each thread in the application domain can have its own distinct copy of the data. When a thread accesses the Value property for the first time, the data is initialized.

The initialization can be done in one of two ways:

The ThreadLocal<T> class implements the IDisposable interface. It's important to dispose of ThreadLocal<T> instances when they are no longer needed to release associated resources, especially if the T type holds unmanaged resources or if you've specified trackAllValues as true.

Example

using System;
using System.Threading;

public class Example
{
    // Create a thread-local variable with a factory function.
    private static ThreadLocal<int> threadLocalCounter =
        new ThreadLocal<int>(() =>
        {
            Console.WriteLine("Initializing counter for thread: {0}", Thread.CurrentThread.ManagedThreadId);
            return 0; // Initial value for each thread
        });

    public static void Main(string[] args)
    {
        // Start multiple threads that all access the same thread-local variable.
        for (int i = 0; i < 3; i++)
        {
            new Thread(Worker).Start();
        }

        // The main thread also has its own value.
        Console.WriteLine("Main thread counter initial value: {0}", threadLocalCounter.Value);
        threadLocalCounter.Value++;
        Console.WriteLine("Main thread counter after increment: {0}", threadLocalCounter.Value);

        // Give threads time to finish (for demonstration purposes)
        Thread.Sleep(2000);

        // Dispose the thread-local variable when done.
        threadLocalCounter.Dispose();
    }

    public static void Worker()
    {
        Console.WriteLine("Thread {0} accessed Value: {1}", Thread.CurrentThread.ManagedThreadId, threadLocalCounter.Value);
        threadLocalCounter.Value++; // Each thread increments its own copy
        Console.WriteLine("Thread {0} incremented value to: {1}", Thread.CurrentThread.ManagedThreadId, threadLocalCounter.Value);

        // Simulate some work
        Thread.Sleep(500);

        Console.WriteLine("Thread {0} final Value: {1}", Thread.CurrentThread.ManagedThreadId, threadLocalCounter.Value);
    }
}

See Also