ThreadStaticAttribute Class

Definition

Indicates that the value of a static field is unique for each thread.

public ref class ThreadStaticAttribute : Attribute
[System.AttributeUsage(System.AttributeTargets.Field, Inherited=false)]
public class ThreadStaticAttribute : Attribute
[System.AttributeUsage(System.AttributeTargets.Field, Inherited=false)]
[System.Serializable]
public class ThreadStaticAttribute : Attribute
[System.AttributeUsage(System.AttributeTargets.Field, Inherited=false)]
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class ThreadStaticAttribute : Attribute
[<System.AttributeUsage(System.AttributeTargets.Field, Inherited=false)>]
type ThreadStaticAttribute = class
    inherit Attribute
[<System.AttributeUsage(System.AttributeTargets.Field, Inherited=false)>]
[<System.Serializable>]
type ThreadStaticAttribute = class
    inherit Attribute
[<System.AttributeUsage(System.AttributeTargets.Field, Inherited=false)>]
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type ThreadStaticAttribute = class
    inherit Attribute
Public Class ThreadStaticAttribute
Inherits Attribute
Inheritance
ThreadStaticAttribute
Attributes

Examples

The following example code demonstrates how to use the ThreadStaticAttribute to ensure that a static field is unique to each thread. In the code, each thread assigns a different request ID to the thread-static field and then simulates request processing across multiple method calls.

using System;
using System.Threading;

class Program
{
    [ThreadStatic]
    private static string? _requestId;

    static void Main()
    {
        Thread thread1 = new(ProcessRequest);
        Thread thread2 = new(ProcessRequest);

        thread1.Start("REQ-001");
        thread2.Start("REQ-002");

        thread1.Join();
        thread2.Join();

        Console.WriteLine("Main thread execution completed.");
    }

    static void ProcessRequest(object? requestId)
    {
        // Assign the request ID to the thread-static field.
        _requestId = requestId as string;

        // Simulate request processing across multiple method calls.
        PerformDatabaseOperation();
        PerformLogging();
    }

    static void PerformDatabaseOperation()
    {
        Console.WriteLine($"Thread {Environment.CurrentManagedThreadId}: Processing DB operation for request {_requestId}");
    }

    static void PerformLogging()
    {
        Console.WriteLine($"Thread {Environment.CurrentManagedThreadId}: Logging request {_requestId}");
    }
}
open System
open System.Threading

type ThreadLocal() =
    [<ThreadStatic; DefaultValue>]
    static val mutable private requestId: string option

    static member PerformLogging() =
        Console.WriteLine($"Thread {Environment.CurrentManagedThreadId}: Logging request {ThreadLocal.requestId.Value}")

    static member PerformDatabaseOperation() =
        Console.WriteLine($"Thread {Environment.CurrentManagedThreadId}: Processing DB operation for request {ThreadLocal.requestId.Value}")

    static member ProcessRequest(reqId: obj) =
        ThreadLocal.requestId <- Some(reqId :?> string)
        ThreadLocal.PerformDatabaseOperation()
        ThreadLocal.PerformLogging()

[<EntryPoint>]
let main _ =
    let thread1 = Thread(ThreadStart(fun () -> ThreadLocal.ProcessRequest("REQ-001")))
    let thread2 = Thread(ThreadStart(fun () -> ThreadLocal.ProcessRequest("REQ-002")))

    thread1.Start()
    thread2.Start()
    thread1.Join()
    thread2.Join()

    Console.WriteLine("Main thread execution completed.")
    0
Imports System
Imports System.Threading

Module Program

    <ThreadStatic>
    Private _requestId As String

    Sub Main()
        Dim thread1 As New Thread(AddressOf ProcessRequest)
        Dim thread2 As New Thread(AddressOf ProcessRequest)

        thread1.Start("REQ-001")
        thread2.Start("REQ-002")

        thread1.Join()
        thread2.Join()

        Console.WriteLine("Main thread execution completed.")
    End Sub

    Sub ProcessRequest(ByVal requestId As Object)
        ' Assign the request ID to the thread-static field
        _requestId = requestId.ToString()

        ' Simulate request processing across multiple method calls
        PerformDatabaseOperation()
        PerformLogging()
    End Sub

    Sub PerformDatabaseOperation()
        Console.WriteLine($"Thread {Environment.CurrentManagedThreadId}: Processing DB operation for request {_requestId}")
    End Sub

    Sub PerformLogging()
        Console.WriteLine($"Thread {Environment.CurrentManagedThreadId}: Logging request {_requestId}")
    End Sub

End Module

Remarks

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.

In addition to applying the ThreadStaticAttribute attribute to a field, you must also define it as static (in C# or F#) or Shared (in Visual Basic).

Note

Don't specify initial values for fields marked with ThreadStaticAttribute. Such initialization occurs only once, when the class constructor executes, and therefore affects only one thread. If you don't specify an initial value, the field will be initialized to its default value if it's a value type, or to null if it's a reference type.

Use this attribute as it is, and don't derive from it.

For more information about using attributes, see Attributes.

Constructors

ThreadStaticAttribute()

Initializes a new instance of the ThreadStaticAttribute class.

Properties

TypeId

When implemented in a derived class, gets a unique identifier for this Attribute.

(Inherited from Attribute)

Methods

Equals(Object)

Returns a value that indicates whether this instance is equal to a specified object.

(Inherited from Attribute)
GetHashCode()

Returns the hash code for this instance.

(Inherited from Attribute)
GetType()

Gets the Type of the current instance.

(Inherited from Object)
IsDefaultAttribute()

When overridden in a derived class, indicates whether the value of this instance is the default value for the derived class.

(Inherited from Attribute)
Match(Object)

When overridden in a derived class, returns a value that indicates whether this instance equals a specified object.

(Inherited from Attribute)
MemberwiseClone()

Creates a shallow copy of the current Object.

(Inherited from Object)
ToString()

Returns a string that represents the current object.

(Inherited from Object)

Explicit Interface Implementations

_Attribute.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr)

Maps a set of names to a corresponding set of dispatch identifiers.

(Inherited from Attribute)
_Attribute.GetTypeInfo(UInt32, UInt32, IntPtr)

Retrieves the type information for an object, which can be used to get the type information for an interface.

(Inherited from Attribute)
_Attribute.GetTypeInfoCount(UInt32)

Retrieves the number of type information interfaces that an object provides (either 0 or 1).

(Inherited from Attribute)
_Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr)

Provides access to properties and methods exposed by an object.

(Inherited from Attribute)

Applies to

See also