Lokální úložiště vláken: statická pole a datové sloty ve vztahu k vláknům
Pomocí místního úložiště spravovaného vlákna (TLS) můžete ukládat data, která jsou jedinečná pro vlákno a doménu aplikace. .NET nabízí dva způsoby použití spravovaného protokolu TLS: statická pole s relativními vlákny a sloty dat.
Pokud můžete očekávat přesné potřeby v době kompilace, použijte statická pole relativní vzhledem k vláknu (pole relativní
Shared
vzhledem k vláknu v jazyce Visual Basic). Statická pole relativní vzhledem k vláknu poskytují nejlepší výkon. Poskytují také výhody kontroly typů v době kompilace.Datové sloty používejte, když se skutečné požadavky můžou objevit jenom za běhu. Datové sloty jsou pomalejší a nešikovnější než statická pole relativní vzhledem k vláknům a data se ukládají jako typ Object, takže je musíte před použitím přetypovat na správný typ.
V nespravovaném jazyce C++ slouží TlsAlloc
k dynamickému přidělování slotů a __declspec(thread)
k deklaraci, že proměnná by měla být přidělena v úložišti relativním vzhledem k vláknům. Statická pole a datové sloty relativní vzhledem k vláknům poskytují spravovanou verzi tohoto chování.
Třídu můžete použít System.Threading.ThreadLocal<T> k vytvoření objektů místních vláken, které jsou inicializovány lazily při prvním použití objektu. Další informace naleznete v tématu Opožděná inicializace.
Jedinečnost dat ve spravovaném protokolu TLS
Bez ohledu na to, jestli používáte statická pole relativní vzhledem k vláknům nebo sloty dat, jsou data ve spravovaném protokolu TLS jedinečná pro kombinaci vláken a domény aplikace.
V doméně aplikace nemůže jedno vlákno upravovat data z jiného vlákna, i když obě vlákna používají stejné pole nebo slot.
Když vlákno přistupuje ke stejnému poli nebo slotu z více domén aplikace, zachová se v každé doméně aplikace samostatná hodnota.
Pokud například vlákno nastaví hodnotu statického pole relativního vlákna, zadá jinou doménu aplikace a pak načte hodnotu pole, hodnota načtená v druhé doméně aplikace se liší od hodnoty v první doméně aplikace. Nastavení nové hodnoty pro pole v druhé doméně aplikace nemá vliv na hodnotu pole v první doméně aplikace.
Podobně když vlákno získá stejný pojmenovaný datový slot ve dvou různých doménách aplikace, data v první doméně aplikace zůstanou nezávislá na datech v druhé doméně aplikace.
Statická pole relativní vzhledem k vláknu
Pokud víte, že část dat je vždy jedinečná pro kombinaci vláken a domény aplikace, použijte ThreadStaticAttribute atribut na statické pole. Pole použijte stejně, jako byste použili jakékoli jiné statické pole. Data v poli jsou jedinečná pro každé vlákno, které je používá.
Statická pole relativní vzhledem k vláknům poskytují lepší výkon než sloty dat a mají výhodu kontroly typů kompilace.
Mějte na paměti, že jakýkoli kód konstruktoru třídy se spustí na prvním vlákně v prvním kontextu, který přistupuje k poli. Ve všech ostatních vláknech nebo kontextech ve stejné doméně aplikace budou pole inicializována na null
(Nothing
v jazyce Visual Basic), pokud jde o odkazové typy nebo výchozí hodnoty, pokud se jedná o typy hodnot. Proto byste neměli spoléhat na konstruktory tříd k inicializaci statických polí relativních pro vlákna. Místo toho se vyhněte inicializaci statických polí relativních vzhledem k vláknům a předpokládejme, že jsou inicializovány na null
(Nothing
) nebo na jejich výchozí hodnoty.
Datové sloty
.NET poskytuje dynamické datové sloty, které jsou jedinečné pro kombinaci vláken a domény aplikace. Existují dva typy datových slotů: pojmenované sloty a nepojmenované sloty. Obě se implementují pomocí LocalDataStoreSlot struktury.
K vytvoření pojmenovaného datového slotu použijte metodu nebo Thread.GetNamedDataSlot metoduThread.AllocateNamedDataSlot. Pokud chcete získat odkaz na existující pojmenovaný slot, předejte jeho název GetNamedDataSlot metodě.
K vytvoření nepojmenovaného datového slotu použijte metodu Thread.AllocateDataSlot .
Pro pojmenované i nepojmenované sloty použijte metody Thread.SetData a Thread.GetData nastavte a načtěte informace v slotu. Jedná se o statické metody, které vždy pracují s daty pro vlákno, které je právě spouští.
Pojmenované sloty můžou být pohodlné, protože slot můžete načíst, když ho potřebujete, předáním jeho názvu GetNamedDataSlot metodě místo zachování odkazu na nepojmenovaný slot. Pokud ale jiná komponenta používá stejný název pro relativní úložiště vlákna a vlákno spustí kód z vaší komponenty i druhé komponenty, mohou tyto dvě komponenty poškodit data ostatních. (Tento scénář předpokládá, že obě komponenty jsou spuštěné ve stejné doméně aplikace a že nejsou navržené tak, aby sdílely stejná data.)