Aktualisiert: November 2007
Legt die Daten im angegebenen Slot auf den derzeit ausgeführten Thread und für die aktuelle Domäne des betreffenden Threads fest. Eine höhere Leistung erzielen Sie, wenn Sie stattdessen Felder verwenden, die mit dem ThreadStaticAttribute-Attribut markiert sind.
Namespace:
System.Threading
Assembly:
mscorlib (in mscorlib.dll)
Visual Basic (Deklaration)
<HostProtectionAttribute(SecurityAction.LinkDemand, SharedState := True, ExternalThreading := True)> _
Public Shared Sub SetData ( _
slot As LocalDataStoreSlot, _
data As Object _
)
Visual Basic (Verwendung)
Dim slot As LocalDataStoreSlot
Dim data As Object
Thread.SetData(slot, data)
[HostProtectionAttribute(SecurityAction.LinkDemand, SharedState = true, ExternalThreading = true)]
public static void SetData(
LocalDataStoreSlot slot,
Object data
)
[HostProtectionAttribute(SecurityAction::LinkDemand, SharedState = true, ExternalThreading = true)]
public:
static void SetData(
LocalDataStoreSlot^ slot,
Object^ data
)
/** @attribute HostProtectionAttribute(SecurityAction.LinkDemand, SharedState = true, ExternalThreading = true) */
public static void SetData(
LocalDataStoreSlot slot,
Object data
)
public static function SetData(
slot : LocalDataStoreSlot,
data : Object
)
Wichtiger Hinweis: |
|---|
.NET Framework stellt zwei Mechanismen für die Verwendung des lokalen Threadspeichers bereit (TLS): threadbezogene statische Felder (Felder, die mit dem ThreadStaticAttribute-Attribut markiert sind) und Datenslots. Threadbezogene statische Felder erzielen eine sehr viel höhere Leistung als Datenslots und ermöglichen eine Typüberprüfung zur Kompilierzeit. Weitere Informationen zum Verwenden von TLS finden Sie unter Lokaler Threadspeicher: Threadbezogene statische Felder und Datenslots. |
Threads verwenden zum Speichern threadspezifischer Daten einen Speichermechanismus mit lokalem Speicher. Die Common Language Runtime ordnet jedem Prozess bei der Generierung ein Datenspeicherarray mit mehreren Slots zu. Der Thread kann einen Datenslot im Datenspeicher reservieren, einen Datenwert im Slot speichern und aus diesem abrufen sowie den Slot für die weitere Verwendung freigeben, nachdem die Threadprozedur beendet und das Thread-Objekt während der Garbage Collection wieder freigegeben wurde. Datenslots sind pro Thread jeweils eindeutig. Diese Daten kann kein anderer Thread (auch kein untergeordneter Thread) abrufen.
vb# Hinweis: |
|---|
SetData ist eine Shared-Methode, die immer auf den gerade ausgeführten Thread angewendet wird, auch wenn sie mit einer Variablen aufgerufen wird, die auf einen anderen Thread verweist. Um Verwirrung zu vermeiden, rufen Sie Shared-Methoden mit dem Klassennamen auf: Thread.SetData(testSlot, "test data"). |
Dieser Abschnitt enthält zwei Codebeispiele. Im ersten Beispiel wird veranschaulicht, wie ein mit dem ThreadStaticAttribute-Attribut markiertes Feld zum Speichern threadbezogener Informationen verwendet wird. Im zweiten Beispiel wird dieselbe Aufgabe mit einem Datenslot realisiert.
Erstes Beispiel
Im folgenden Beispiel wird veranschaulicht, wie ein mit dem ThreadStaticAttribute-Attribut markiertes Feld zum Speichern threadbezogener Informationen verwendet wird. Dieses Verfahren erzielt eine höhere Leistung als das Verfahren im zweiten Beispiel.
Imports System
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
<ThreadStaticAttribute> _
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 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
{
[ThreadStaticAttribute]
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
*/
using namespace System;
using namespace System::Threading;
ref class ThreadData
{
private:
[ThreadStaticAttribute]
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
*/
Zweites Beispiel
Im folgenden Beispiel wird die Verwendung eines benannten Datenslots zum Speichern threadbezogener Informationen veranschaulicht.
Option Explicit
Option Strict
Imports System
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 SlotExample.SlotTest)
newThreads(i).Start()
Next i
End Sub
End Class
Public Class SlotExample
Shared randomGenerator As Random = New Random()
Shared Sub SlotTest()
' Set different data in each thread's data slot.
Thread.SetData( _
Thread.GetNamedDataSlot("Random"), _
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( _
Thread.GetNamedDataSlot("Random")).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 is still: {1,3}", _
AppDomain.GetCurrentThreadId().ToString(), _
Thread.GetData( _
Thread.GetNamedDataSlot("Random")).ToString())
' Allow time for other threads to show their data,
' then demonstrate that any code a thread executes
' has access to the thread's named data slot.
Thread.Sleep(1000)
Dim o As New Other()
o.ShowSlotData()
End Sub
End Class
Public Class Other
Public Sub ShowSlotData()
' This method has no access to the data in the SlotExample
' class, but when executed by a thread it can obtain
' the thread's data from a named slot.
Console.WriteLine("Other code displays data in thread_{0}'s data slot: {1,3}", _
AppDomain.GetCurrentThreadId().ToString(), _
Thread.GetData( _
Thread.GetNamedDataSlot("Random")).ToString())
End Sub
End Class
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 = new Random();
public static void SlotTest()
{
// Set different data in each thread's data slot.
Thread.SetData(
Thread.GetNamedDataSlot("Random"),
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(
Thread.GetNamedDataSlot("Random")).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 is still: {1,3}",
AppDomain.GetCurrentThreadId().ToString(),
Thread.GetData(
Thread.GetNamedDataSlot("Random")).ToString());
// Allow time for other threads to show their data,
// then demonstrate that any code a thread executes
// has access to the thread's named data slot.
Thread.Sleep(1000);
Other o = new Other();
o.ShowSlotData();
}
}
public class Other
{
public void ShowSlotData()
{
// This method has no access to the data in the Slot
// class, but when executed by a thread it can obtain
// the thread's data from a named slot.
Console.WriteLine("Other code displays data in thread_{0}'s data slot: {1,3}",
AppDomain.GetCurrentThreadId().ToString(),
Thread.GetData(
Thread.GetNamedDataSlot("Random")).ToString());
}
}
using namespace System;
using namespace System::Threading;
ref class Other
{
public:
void ShowSlotData()
{
// This method has no access to the data in the Slot
// class, but when executed by a thread it can obtain
// the thread's data from a named slot.
Console::WriteLine( "Other code displays data in thread_{0}'s data slot: {1,3}", AppDomain::GetCurrentThreadId(), Thread::GetData( Thread::GetNamedDataSlot( "Random" ) )->ToString() );
}
};
ref class Slot
{
private:
static Random^ randomGenerator = gcnew Random;
public:
static void SlotTest()
{
// Set different data in each thread's data slot.
Thread::SetData( Thread::GetNamedDataSlot( "Random" ), 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( Thread::GetNamedDataSlot( "Random" ) )->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 is still: {1,3}", AppDomain::GetCurrentThreadId().ToString(), Thread::GetData( Thread::GetNamedDataSlot( "Random" ) )->ToString() );
// Allow time for other threads to show their data,
// then demonstrate that any code a thread executes
// has access to the thread's named data slot.
Thread::Sleep( 1000 );
Other^ o = gcnew Other;
o->ShowSlotData();
}
};
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();
}
}
import System.*;
import System.Threading.*;
import System.Threading.Thread;
class Test
{
public static void main(String[] args)
{
Thread newThreads[] = new Thread[4];
for (int i = 0; i < newThreads.length; i++) {
newThreads[i] = new Thread(new ThreadStart(Slot.SlotTest));
newThreads[i].Start();
}
} //main
} //Test
class Slot
{
private static Random randomGenerator = new Random();
public static void SlotTest()
{
// Set different data in each thread's data slot.
Thread.SetData(Thread.GetNamedDataSlot("Random"),
new Integer(randomGenerator.Next(1, 200)));
// Write the data from each thread's data slot.
Console.WriteLine("Data in thread_{0}'s data slot: {1,3}",
String.valueOf(AppDomain.GetCurrentThreadId()),
Thread.GetData(Thread.GetNamedDataSlot("Random")).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 is still: {1,3}",
String.valueOf(AppDomain.GetCurrentThreadId()),
Thread.GetData(Thread.GetNamedDataSlot("Random")).toString());
// Allow time for other threads to show their data,
// then demonstrate that any code a thread executes
// has access to the thread's named data slot.
Thread.Sleep(1000);
Other o = new Other();
o.ShowSlotData();
} //SlotTest
} //Slot
public class Other
{
public void ShowSlotData()
{
// This method has no access to the data in the Slot
// class, but when executed by a thread it can obtain
// the thread's data from a named slot.
Console.WriteLine("Other code displays data in "
+ "thread_{0}'s data slot: {1,3}",
String.valueOf(AppDomain.GetCurrentThreadId()),
Thread.GetData(Thread.GetNamedDataSlot("Random")).ToString());
} //ShowSlotData
} //Other
Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98, Windows CE, Windows Mobile für Smartphone, Windows Mobile für Pocket PC, Xbox 360
.NET Framework und .NET Compact Framework unterstützen nicht alle Versionen sämtlicher Plattformen. Eine Liste der unterstützten Versionen finden Sie unter Systemanforderungen für .NET Framework.
.NET Framework
Unterstützt in: 3.5, 3.0, 2.0, 1.1, 1.0
.NET Compact Framework
Unterstützt in: 3.5, 2.0, 1.0
XNA Framework
Unterstützt in: 2.0, 1.0
Referenz
Weitere Ressourcen