Dela via


Trådlokal lagring: Trådrelativa statiska fält och datafack

Du kan använda TLS (Managed Thread Local Storage) för att lagra data som är unika för en tråd- och programdomän. .NET tillhandahåller två sätt att använda hanterad TLS: trådrelativa statiska fält och datafack.

  • Använd trådrelativa statiska fält (trådrelativa Shared fält i Visual Basic) om du kan förutse dina exakta behov vid kompileringstillfället. Trådrelativa statiska fält ger bästa prestanda. De ger dig också fördelarna med kompileringstidstypkontroll.

  • Använd datafack när dina faktiska krav kan identifieras endast vid körning. Datafack är långsammare och mer besvärliga att använda än trådrelativa statiska fält, och data lagras som typ Object, så du måste omvandla dem till rätt typ innan du använder dem.

I ohanterad C++ använder TlsAlloc du för att allokera platser dynamiskt och __declspec(thread) för att deklarera att en variabel ska allokeras i trådrelativ lagring. Trådrelativa statiska fält och datafack ger den hanterade versionen av det här beteendet.

Du kan använda System.Threading.ThreadLocal<T> klassen för att skapa trådlokala objekt som initieras lazily när objektet först används. Mer information finns i Lazy Initialization (Lat initiering).

Unikhet för data i hanterad TLS

Oavsett om du använder trådrelativa statiska fält eller datafack är data i hanterad TLS unika för kombinationen av tråd- och programdomän.

  • Inom en programdomän kan en tråd inte ändra data från en annan tråd, även om båda trådarna använder samma fält eller fack.

  • När en tråd kommer åt samma fält eller fack från flera programdomäner underhålls ett separat värde i varje programdomän.

Om en tråd till exempel anger värdet för ett trådrelativt statiskt fält, anger en annan programdomän och sedan hämtar värdet för fältet, skiljer sig det värde som hämtas i den andra programdomänen från värdet i den första programdomänen. Att ange ett nytt värde för fältet i den andra programdomänen påverkar inte fältets värde i den första programdomänen.

På samma sätt, när en tråd får samma namngivna datafack i två olika programdomäner, förblir data i den första programdomänen oberoende av data i den andra programdomänen.

Trådrelativa statiska fält

Om du vet att en databit alltid är unik för en kombination av tråd och programdomän använder du ThreadStaticAttribute attributet för det statiska fältet. Använd fältet på samma sätt som med andra statiska fält. Data i fältet är unika för varje tråd som använder den.

Trådrelativa statiska fält ger bättre prestanda än datafack och har fördelen med kompileringstypkontroll.

Tänk på att all klasskonstruktorkod körs på den första tråden i den första kontexten som kommer åt fältet. I alla andra trådar eller kontexter i samma programdomän initieras fälten till null (Nothing i Visual Basic) om de är referenstyper eller till deras standardvärden om de är värdetyper. Därför bör du inte förlita dig på klasskonstruktorer för att initiera trådrelativa statiska fält. Undvik i stället att initiera trådrelativa statiska fält och anta att de initieras till null (Nothing) eller deras standardvärden.

Datafack

.NET tillhandahåller dynamiska datafack som är unika för en kombination av tråd- och programdomän. Det finns två typer av datafack: namngivna platser och namnlösa platser. Båda implementeras med hjälp LocalDataStoreSlot av strukturen.

För både namngivna och namnlösa platser använder du Thread.SetData metoderna och Thread.GetData för att ange och hämta informationen i facket. Det här är statiska metoder som alltid fungerar på data för den tråd som för närvarande kör dem.

Namngivna platser kan vara praktiska, eftersom du kan hämta facket när du behöver det genom att skicka dess namn till GetNamedDataSlot metoden, i stället för att upprätthålla en referens till ett namnlöst fack. Men om en annan komponent använder samma namn för sin trådrelativa lagring och en tråd kör kod från både komponenten och den andra komponenten kan de två komponenterna skada varandras data. (Det här scenariot förutsätter att båda komponenterna körs i samma programdomän och att de inte är utformade för att dela samma data.)

Se även