Thread.GetData(LocalDataStoreSlot) 方法

定義

從目前執行緒上、目前執行緒之目前定義域中的指定位置擷取數值。 為獲得較佳的效能,請改用以 ThreadStaticAttribute 屬性標示的欄位。

public:
 static System::Object ^ GetData(LocalDataStoreSlot ^ slot);
public static 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

傳回

Object

擷取的數值。

範例

本節包含兩個程式碼範例。 第一個範例示範如何使用標記有屬性的欄位 ThreadStaticAttribute 來保存執行緒特定的資訊。 第二個範例顯示如何使用資料位置來執行相同的動作。

第一個範例

下列範例示範如何使用標記為的欄位 ThreadStaticAttribute 來保存執行緒特定的資訊。 這項技術提供的效能比第二個範例中所示的技巧更好。

using namespace System;
using namespace System::Threading;

ref class ThreadData
{
private:
   [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 );
   }
};

int main()
{
   for ( int i = 0; i < 3; i++ )
   {
      Thread^ newThread = 
          gcnew Thread( gcnew ThreadStart( 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
 */
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
 */
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

第二個範例

下列範例示範如何使用資料位置來儲存執行緒特定的資訊。

using namespace System;
using namespace System::Threading;
ref class Slot
{
private:
   static Random^ randomGenerator;
   static LocalDataStoreSlot^ localSlot;
   static Slot()
   {
      randomGenerator = gcnew 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() );
   }

};

int main()
{
   array<Thread^>^newThreads = gcnew array<Thread^>(4);
   for ( int i = 0; i < newThreads->Length; i++ )
   {
      newThreads[ i ] = gcnew Thread( gcnew ThreadStart( &Slot::SlotTest ) );
      newThreads[ i ]->Start();

   }
}
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());
    }
}
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

備註

重要

.NET Framework 提供兩種機制,可讓您使用執行緒區域儲存區 (TLS) :執行緒相關的靜態欄位 (也就是說,以 ThreadStaticAttribute 屬性) 和資料位置標記的欄位。 執行緒相關的靜態欄位提供比資料插槽更好的效能,並啟用編譯時間類型檢查。 如需使用 TLS 的詳細資訊,請參閱執行緒區域儲存體: Thread-Relative 靜態欄位和資料槽

執行緒使用本機存放區記憶體機制來儲存執行緒特定資料。 Common language runtime 會在每個進程建立時,將多個位置的資料存放區陣列配置給每個進程。 執行緒可以配置資料存放區中的資料位置、儲存並取出位置中的資料值,以及釋放位置以線上程到期之後重複使用。 每個執行緒的資料插槽都是唯一的。 沒有其他執行緒 (甚至是子執行緒) 可以取得該資料。

注意

GetDataShared 一律套用至目前執行中線程的方法,即使您使用參考另一個執行緒的變數來呼叫它也是一樣。 若要避免混淆,請在呼叫方法時使用類別名稱 SharedDim test As Object = Thread.GetData(testSlot)

適用於

另請參閱