Thread.GetData(LocalDataStoreSlot) メソッド

定義

現在のスレッドの現在のドメイン内で、現在のスレッドの指定されたスロットから値を取得します。 パフォーマンスを向上させるには、代わりに ThreadStaticAttribute 属性でマークされているフィールドを使用します。

public:
 static System::Object ^ GetData(LocalDataStoreSlot ^ slot);
public static object GetData(LocalDataStoreSlot slot);
static member GetData : LocalDataStoreSlot -> obj
Public Shared Function GetData (slot As LocalDataStoreSlot) As Object

パラメーター

slot
LocalDataStoreSlot

値の取得元となる LocalDataStoreSlot

返品

取得した値。

このセクションには、2 つのコード例が含まれています。 最初の例では、 ThreadStaticAttribute 属性でマークされたフィールドを使用して、スレッド固有の情報を保持する方法を示します。 2 番目の例は、データ スロットを使用して同じことを行う方法を示しています。

最初の例

次の例は、 ThreadStaticAttribute でマークされたフィールドを使用して、スレッド固有の情報を保持する方法を示しています。 この手法は、2 番目の例に示されている手法よりも優れたパフォーマンスを提供します。

using System;
using System.Threading;

class Test
{
    static void Main()
    {
        for(int i = 0; i < 3; i++)
        {
            Thread newThread = new Thread(ThreadData.ThreadStaticDemo);
            newThread.Start();
        }
    }
}

class ThreadData
{
    [ThreadStatic]
    static int threadSpecificData;

    public static void ThreadStaticDemo()
    {
        // Store the managed thread id for each thread in the static
        // variable.
        threadSpecificData = Thread.CurrentThread.ManagedThreadId;
      
        // Allow other threads time to execute the same code, to show
        // that the static data is unique to each thread.
        Thread.Sleep( 1000 );

        // Display the static data.
        Console.WriteLine( "Data for managed thread {0}: {1}", 
            Thread.CurrentThread.ManagedThreadId, threadSpecificData );
    }
}

/* This code example produces output similar to the following:

Data for managed thread 4: 4
Data for managed thread 5: 5
Data for managed thread 3: 3
 */
open System
open System.Threading

type ThreadData() =
    // Create a static variable to hold the data for each thread.
    [<ThreadStatic; DefaultValue>]
    static val mutable private threadSpecificData : int

    static member ThreadStaticDemo() =
        // Store the managed thread id for each thread in the static
        // variable.
        ThreadData.threadSpecificData <- Thread.CurrentThread.ManagedThreadId
        
        // Allow other threads time to execute the same code, to show
        // that the static data is unique to each thread.
        Thread.Sleep 1000

        // Display the static data.
        printfn $"Data for managed thread {Thread.CurrentThread.ManagedThreadId}: {ThreadData.threadSpecificData}" 

for i = 0 to 2 do 
    let newThread = Thread ThreadData.ThreadStaticDemo
    newThread.Start()

// This code example produces output similar to the following:
//       Data for managed thread 4: 4
//       Data for managed thread 5: 5
//       Data for managed thread 3: 3
Imports System.Threading

Class Test

    <MTAThread> _
    Shared Sub Main()

        For i As Integer = 1 To 3
            Dim newThread As New Thread(AddressOf ThreadData.ThreadStaticDemo)
            newThread.Start()
        Next i

    End Sub

End Class

Class ThreadData

    <ThreadStatic> _
    Shared threadSpecificData As Integer

    Shared Sub ThreadStaticDemo()

        ' Store the managed thread id for each thread in the static
        ' variable.
        threadSpecificData = Thread.CurrentThread.ManagedThreadId
      
        ' Allow other threads time to execute the same code, to show
        ' that the static data is unique to each thread.
        Thread.Sleep( 1000 )

        ' Display the static data.
        Console.WriteLine( "Data for managed thread {0}: {1}", _
            Thread.CurrentThread.ManagedThreadId, threadSpecificData )

    End Sub

End Class

' This code example produces output similar to the following:
'
'Data for managed thread 4: 4
'Data for managed thread 5: 5
'Data for managed thread 3: 3

2 番目の例

次の例では、データ スロットを使用してスレッド固有の情報を格納する方法を示します。

using System;
using System.Threading;

class Test
{
    static void Main()
    {
        Thread[] newThreads = new Thread[4];
        for(int i = 0; i < newThreads.Length; i++)
        {
            newThreads[i] = new Thread(
                new ThreadStart(Slot.SlotTest));
            newThreads[i].Start();
        }
    }
}

class Slot
{
    static Random randomGenerator;
    static LocalDataStoreSlot localSlot;

    static Slot()
    {
        randomGenerator = new Random();
        localSlot = Thread.AllocateDataSlot();
    }

    public static void SlotTest()
    {
        // Set different data in each thread's data slot.
        Thread.SetData(localSlot, randomGenerator.Next(1, 200));

        // Write the data from each thread's data slot.
        Console.WriteLine("Data in thread_{0}'s data slot: {1,3}", 
            AppDomain.GetCurrentThreadId().ToString(),
            Thread.GetData(localSlot).ToString());

        // Allow other threads time to execute SetData to show
        // that a thread's data slot is unique to the thread.
        Thread.Sleep(1000);

        Console.WriteLine("Data in thread_{0}'s data slot: {1,3}", 
            AppDomain.GetCurrentThreadId().ToString(),
            Thread.GetData(localSlot).ToString());
    }
}
open System
open System.Threading

module Slot =
    let randomGenerator = Random()
    let localSlot = Thread.AllocateDataSlot()


    let slotTest () =
        // Set different data in each thread's data slot.
        Thread.SetData(localSlot, randomGenerator.Next(1, 200))

        // Write the data from each thread's data slot.
        printfn $"Data in thread_{AppDomain.GetCurrentThreadId()}'s data slot: {Thread.GetData localSlot, 3}"

        // Allow other threads time to execute SetData to show
        // that a thread's data slot is unique to the thread.
        Thread.Sleep 1000

        printfn $"Data in thread_{AppDomain.GetCurrentThreadId()}'s data slot: {Thread.GetData localSlot, 3}"

let newThreads =
    [| for _ = 0 to 3 do
           let thread = Thread Slot.slotTest
           thread.Start()
           thread |]
Imports System.Threading

Class Test

    <MTAThread> _
    Shared Sub Main()
        Dim newThreads(3) As Thread
        For i As Integer = 0 To newThreads.Length - 1
            newThreads(i) = New Thread(AddressOf Slot.SlotTest)
            newThreads(i).Start()
        Next i
    End Sub

End Class

Public Class Slot

    Shared randomGenerator As Random
    Shared localSlot As LocalDataStoreSlot

    Shared Sub New()
        randomGenerator = new Random()
        localSlot = Thread.AllocateDataSlot()
    End Sub

    Shared Sub SlotTest()

        ' Set different data in each thread's data slot.
        Thread.SetData(localSlot, randomGenerator.Next(1, 200))

        ' Write the data from each thread's data slot.
        Console.WriteLine("Data in thread_{0}'s data slot: {1,3}", _
            AppDomain.GetCurrentThreadId().ToString(), _
            Thread.GetData(localSlot).ToString())

        ' Allow other threads time to execute SetData to show
        ' that a thread's data slot is unique to the thread.
        Thread.Sleep(1000)

        ' Write the data from each thread's data slot.
        Console.WriteLine("Data in thread_{0}'s data slot: {1,3}", _
            AppDomain.GetCurrentThreadId().ToString(), _
            Thread.GetData(localSlot).ToString())
    End Sub

End Class

注釈

Important

.NET Framework には、スレッド ローカル ストレージ (TLS) を使用するための 2 つのメカニズムが用意されています。スレッド相対静的フィールド (つまり、ThreadStaticAttribute 属性でマークされているフィールド) とデータ スロットです。 スレッド相対静的フィールドは、データ スロットよりもはるかに優れたパフォーマンスを提供し、コンパイル時の型チェックを有効にします。 TLS の使用の詳細については、「 スレッド ローカル ストレージ: 静的フィールドとデータ スロットの Thread-Relative」を参照してください。

スレッドは、スレッド固有のデータを格納するためにローカル ストア メモリ メカニズムを使用します。 共通言語ランタイムは、作成時に各プロセスにマルチスロット データ ストア配列を割り当てます。 スレッドは、データ ストアにデータ スロットを割り当て、スロットにデータ値を格納および取得し、スレッドの有効期限が切れた後に再利用できるようにスロットを解放できます。 データ スロットはスレッドごとに一意です。 他のスレッド (子スレッドでもない) は、そのデータを取得できません。

Note

GetData は、別のスレッドを参照する変数を使用して呼び出した場合でも、常に現在実行中のスレッドに適用される Shared メソッドです。 混乱を避けるために、 Shared メソッド Dim test As Object = Thread.GetData(testSlot)を呼び出すときにクラス名を使用します。

適用対象

こちらもご覧ください