Jak działa [ThreadStatic]
atrybut? Założyłem, że kompilator wyemituje trochę IL, aby załadować / pobrać wartość w TLS, ale patrząc na dezasemblację, wydaje się, że nie robi tego na tym poziomie.
W dalszej kolejności, co się stanie, jeśli umieścisz go na niestatycznym elemencie? Deweloper popełnił ten błąd, a kompilator nawet nie daje ostrzeżenia.
Aktualizacja
Odpowiedź na drugie pytanie: ThreadStatic zmodyfikowana za pomocą statycznego C #
c#
static
threadstatic
joshperry
źródło
źródło
Odpowiedzi:
Semantyka implementacji wątku statycznego jest poniżej poziomu IL, w kompilatorze jit .NET. Kompilatory, które emitują do IL, takie jak VB.NET i C #, nie muszą nic wiedzieć o Win32 TLS, aby emitować kod IL, który może odczytywać i zapisywać zmienną, która ma atrybut ThreadStatic. O ile C # wie, nie ma nic specjalnego w tej zmiennej - jest to tylko lokalizacja do czytania i pisania. Fakt, że ma przypisany atrybut, nie ma znaczenia dla C #. C # musi tylko wiedzieć, aby emitować instrukcje odczytu lub zapisu IL dla tej nazwy symbolu.
„Podnoszenie ciężarów” jest wykonywane przez rdzeń środowiska CLR, które jest odpowiedzialne za sprawienie, by IL działał na określonej architekturze sprzętowej.
To by również wyjaśniało, dlaczego umieszczenie atrybutu na niewłaściwym (niestatycznym) symbolu nie powoduje reakcji kompilatora. Kompilator nie wie, jakiej specjalnej semantyki wymaga atrybut. Jednak narzędzia do analizy kodu, takie jak FX / Cop, powinny o tym wiedzieć.
Można na to spojrzeć inaczej: CIL definiuje zestaw zakresów pamięci: pamięć statyczną (globalną), pamięć składową i pamięć stosową. TLS nie znajduje się na tej liście, bardzo prawdopodobne, ponieważ TLS nie musi znajdować się na tej liście. Jeśli instrukcje odczytu i zapisu IL są wystarczające, aby uzyskać dostęp do TLS, gdy symbol jest oznaczony atrybutem TLS, dlaczego IL miałby mieć jakąś specjalną reprezentację lub sposób traktowania TLS? To nie jest potrzebne.
źródło
Możesz pomyśleć, że pole oznaczone ThreadStatic jest dołączone do wątku, a jego żywotność jest porównywalna z czasem życia wątku.
Więc w pseudokodzie
ThreadStatic
jest podobne (semantycznie) do posiadania klucza-wartości dołączonej do wątku:ale składnia jest trochę łatwiejsza:
Uważam, że jest to ignorowane:
Dodatkowo warto wspomnieć, że
ThreadStatic
nie wymaga żadnego mechanizmu synchronizacji w porównaniu do zwykłych pól statycznych (ponieważ stan nie jest współdzielony).źródło
"MyClass.myVariable"
, prawda?TransactionScope
ponieważ przechowują tam różnego rodzaju rzeczy dla zakresu ( referenceource.microsoft.com/#System.Transactions/System/… )[ThreadStatic] tworzy izolowane wersje tej samej zmiennej w każdym wątku.
Przykład:
źródło
Pola oznaczone
[ThreadStatic]
są tworzone w Thread Local Storage, więc każdy wątek ma swoją własną kopię pola, tj. Zakres pól jest lokalny dla wątku.Dostęp do pól TLS uzyskuje się przez rejestry segmentów gs / fs. Te segmenty są używane przez jądra systemu operacyjnego do uzyskiwania dostępu do pamięci specyficznej dla wątków. Robi to jądro systemu operacyjnego.
źródło