Threadlokaler Speicher: Threadbezogene statische Felder und DatenslotsThread Local Storage: Thread-Relative Static Fields and Data Slots

Sie können verwalteten lokalen Threadspeicher (TLS, Thread Local Storage) zum Speichern von Daten verwenden, die für einen Thread und die Anwendungsdomäne eindeutig sind.You can use managed thread local storage (TLS) to store data that is unique to a thread and application domain. .NET Framework bietet zwei Möglichkeiten zur Verwendung von verwaltetem TLS: threadbezogene statische Felder und Datenslots.The .NET Framework provides two ways to use managed TLS: thread-relative static fields and data slots.

  • Verwenden Sie threadbezogene statische Felder (threadbezogene Shared-Felder in Visual Basic), wenn Sie Ihre Anforderungen zum Zeitpunkt der Kompilierung exakt bestimmen können.Use thread-relative static fields (thread-relative Shared fields in Visual Basic) if you can anticipate your exact needs at compile time. Threadbezogene statische Felder bieten die beste Leistung.Thread-relative static fields provide the best performance. Außerdem bieten sie Ihnen die Vorteile der Typüberprüfung zur Kompilierzeit.They also give you the benefits of compile-time type checking.

  • Verwenden Sie Datenslots, wenn die tatsächlichen Anforderungen voraussichtlich nur zur Laufzeit ermittelt werden können.Use data slots when your actual requirements might be discovered only at run time. Datenslots sind langsamer und umständlicher zu verwenden als threadbezogene statische Felder, und Daten werden als Typ Object gespeichert, sodass Sie sie in den richtigen Typ umwandeln müssen, bevor Sie sie verwenden.Data slots are slower and more awkward to use than thread-relative static fields, and data is stored as type Object, so you must cast it to the correct type before you use it.

Ordnen Sie Slots in nicht verwaltetem C++ mit TlsAlloc dynamisch zu, und deklarieren Sie mit __declspec(thread), dass eine Variable in threadbezogenem Speicher zugewiesen werden soll.In unmanaged C++, you use TlsAlloc to allocate slots dynamically and __declspec(thread) to declare that a variable should be allocated in thread-relative storage. Threadbezogene statische Felder und Datenslots stellen die verwaltete Version dieses Verhaltens bereit.Thread-relative static fields and data slots provide the managed version of this behavior.

In .NET Framework 4 können Sie mit der System.Threading.ThreadLocal<T>-Klasse threadlokale Objekte erstellen, die verzögert initialisiert werden, wenn das Objekt zuerst genutzt wird.In the .NET Framework 4, you can use the System.Threading.ThreadLocal<T> class to create thread-local objects that are initialized lazily when the object is first consumed. Weitere Informationen finden Sie unter Verzögerte Initialisierung.For more information, see Lazy Initialization.

Eindeutigkeit der Daten im verwalteten TLSUniqueness of Data in Managed TLS

Ob Sie threadbezogene statische Felder oder Datenslots verwenden, Daten in verwaltetem TLS sind für die Kombination von Thread und Anwendungsdomäne eindeutig.Whether you use thread-relative static fields or data slots, data in managed TLS is unique to the combination of thread and application domain.

  • Innerhalb einer Anwendungsdomäne kann ein Thread Daten aus einem anderen Thread auch dann nicht ändern, wenn beide Threads dasselbe Feld oder denselben Slot verwenden.Within an application domain, one thread cannot modify data from another thread, even when both threads use the same field or slot.

  • Wenn ein Thread von mehreren Anwendungsdomänen aus auf dasselbe Feld oder denselben Slot zugreift, wird in jeder Anwendungsdomäne ein separater Wert beibehalten.When a thread accesses the same field or slot from multiple application domains, a separate value is maintained in each application domain.

Wenn ein Thread z.B. den Wert eines threadbezogenen statischen Felds festlegt, in eine andere Anwendungsdomäne eintritt und dann den Wert des Felds abruft, unterscheidet sich der in der zweiten Anwendungsdomäne abgerufene Wert von dem Wert in der ersten Anwendungsdomäne.For example, if a thread sets the value of a thread-relative static field, enters another application domain, and then retrieves the value of the field, the value retrieved in the second application domain differs from the value in the first application domain. Das Festlegen eines neuen Werts für das Feld in der zweiten Anwendungsdomäne wirkt sich nicht auf den Wert des Felds in der ersten Anwendungsdomäne aus.Setting a new value for the field in the second application domain does not affect the field's value in the first application domain.

Auch wenn ein Thread denselben benannten Datenslot in zwei unterschiedlichen Anwendungsdomänen abruft, bleiben die Daten in der ersten Anwendungsdomäne unabhängig von den Daten in der zweiten Anwendungsdomäne.Similarly, when a thread gets the same named data slot in two different application domains, the data in the first application domain remains independent of the data in the second application domain.

Threadbezogene statische FelderThread-Relative Static Fields

Wenn Sie wissen, dass ein Datenstück für eine Kombination aus Thread und Anwendungsdomäne immer eindeutig ist, wenden Sie das ThreadStaticAttribute-Attribut auf das statische Feld an.If you know that a piece of data is always unique to a thread and application-domain combination, apply the ThreadStaticAttribute attribute to the static field. Verwenden Sie das Feld wie jedes andere statische Feld.Use the field as you would use any other static field. Die Daten im Feld sind für jeden Thread eindeutig, der sie verwendet.The data in the field is unique to each thread that uses it.

Threadbezogene statische Felder bieten bessere Leistung als Datenslots und haben den Vorteil der Typüberprüfung zur Kompilierzeit.Thread-relative static fields provide better performance than data slots and have the benefit of compile-time type checking.

Denken Sie daran, dass Klassenkonstruktorcode auf dem ersten Thread im ersten Kontext ausgeführt wird, der auf das Feld zugreift.Be aware that any class constructor code will run on the first thread in the first context that accesses the field. In allen anderen Threads oder Kontexten in derselben Anwendungsdomäne werden die Felder mit null (Nothing in Visual Basic) initialisiert, wenn sie Verweistypen sind, oder mit ihren Standardwerten, wenn sie Werttypen sind.In all other threads or contexts in the same application domain, the fields will be initialized to null (Nothing in Visual Basic) if they are reference types, or to their default values if they are value types. Aus diesem Grund sollten Sie sich beim Initialisieren threadbezogener statischer Felder nicht auf Klassenkonstruktoren verlassen.Therefore, you should not rely on class constructors to initialize thread-relative static fields. Vermeiden Sie stattdessen das Initialisieren threadbezogener statischer Felder, und setzen Sie voraus, dass sie mit null (Nothing) oder ihren Standardwerten initialisiert werden.Instead, avoid initializing thread-relative static fields and assume that they are initialized to null (Nothing) or to their default values.

DatenslotsData Slots

.NET Framework bietet dynamische Datenslots, die für eine Kombination aus Thread und Anwendungsdomäne eindeutig sind.The .NET Framework provides dynamic data slots that are unique to a combination of thread and application-domain. Es gibt zwei Arten von Datenslots: benannte und nicht benannte Slots.There are two types of data slots: named slots and unnamed slots. Beide werden mithilfe der LocalDataStoreSlot-Struktur implementiert.Both are implemented by using the LocalDataStoreSlot structure.

Verwenden Sie für benannte und unbenannte Slots die Thread.SetData- und Thread.GetData-Methode zum Festlegen und Abrufen der Daten im Slot.For both named and unnamed slots, use the Thread.SetData and Thread.GetData methods to set and retrieve the information in the slot. Hierbei handelt es sich um statische Methoden, die immer für den Thread, der sie derzeit ausführt, auf die Daten angewendet werden.These are static methods that always act on the data for the thread that is currently executing them.

Benannte Slots sind praktisch, da Sie den Slot bei Bedarf abrufen können, indem Sie seinen Namen der GetNamedDataSlot-Methode übergeben, statt einen Verweis auf einen unbenannten Slot beizubehalten.Named slots can be convenient, because you can retrieve the slot when you need it by passing its name to the GetNamedDataSlot method, instead of maintaining a reference to an unnamed slot. Wenn allerdings eine andere Komponente denselben Namen für ihren threadbezogenen Speicher verwendet, und ein Thread sowohl Code aus Ihrer Komponente als auch der anderen ausführt, könnten die zwei Komponenten sich gegenseitig ihre Daten beschädigen.However, if another component uses the same name for its thread-relative storage and a thread executes code from both your component and the other component, the two components might corrupt each other's data. (Dieses Szenario setzt voraus, dass beide Komponenten in derselben Anwendungsdomäne ausgeführt werden und nicht zur gemeinsamen Nutzung derselben Daten konzipiert sind.)(This scenario assumes that both components are running in the same application domain, and that they are not designed to share the same data.)

Siehe auchSee also