2010-11-14 14 views
7

Wydaje mi się to dziwnym wyborem, że obecne informacje o kulturze (CurrentCulture i/lub CurrentUICulture) są właściwością bieżącego wątku. Przynajmniej wydaje się, że zakres takiej rzeczy powinien być o jeden poziom wyższy, na poziomie procesu.Dlaczego CurrentCulture jest właściwością Thread?

Ale te rzeczy zwykle mają sens po usłyszeniu racjonalnego uzasadnienia. Może to być pouczające, aby dowiedzieć się, dlaczego projektanci .NET zdecydowali, że wątek jest właściwym miejscem do umieszczenia tej właściwości.

Odpowiedz

10

Przede wszystkim nie był to ich wybór. Ta decyzja została podjęta długo przed ich rozpoczęciem, kultura jest własnością wątku systemu operacyjnego. Przejrzyj dokumenty SDK dla funkcji API Get/SetThreadLocale(), na przykład.

To nie wyjaśnia tego całkowicie, zwirtualizowały one inne funkcje systemu operacyjnego, aczkolwiek trudno je poddać wirtualizacji, ponieważ wiele interfejsów API jest wrażliwych na zmiany kulturowe, szczególnie te związane z architekturą COM.

Kolejnym dobrym powodem jest to, że zmiana całego procesu kultury jest tak trudna do zrealizowania. Jest to nierozwiązywalny stan wyścigu. Niektóre inne wątki mogą znajdować się w trakcie formatowania danych o powinowactwie do kultury. Podczas gdy blokada będzie działać, aby uniemożliwić mu korzystanie z właściwości kultury, tak jak się zmienia, może uniemożliwić jej zmianę w środku łańcucha wywołań formatujących. Wymagałoby to od nich pewnego rodzaju blokady globalnej i trzymania jej przez cały czas trwania zadania formatowania. Zakleszczenie jest prawdopodobnie bardzo.

Jest jeszcze jeden aspekt tego, który uważam za prawdziwy problem. Jest powiązany z właściwością Thread.ExecutionContext. Struktura używa tego do "przepływu" stanu wątku z jednego wątku do drugiego. Bardzo niejasne, ale ważne, aby przesłać rzeczy takie jak kontekst bezpieczeństwa do wątku roboczego. Byłoby idealnie, gdyby kontekst ten mógł również nasycić kulturę, abyś mógł być pewien, że każdy z uruchomionych pracowników ma tę samą kulturę, którą wybrałeś, a nie domyślny system operacyjny.

Nie wiem, nie wiem dlaczego. Prawdopodobnie dlatego, że podałem pierwszy powód. To, że dokonuje, powoduje jednak, że zmiana kultury nici jest bardzo niebezpieczna. Rodzaj błędów, które mogą powodować, jest subtelny. Podobnie jak tworzenie SortedDictionary z ciągiem znaków jako kluczem w głównym wątku z kulturą domyślną niekanałową systemu operacyjnego. Następnie dowiadujemy się, że wątek roboczy nie może czasem znaleźć żadnych informacji, ponieważ reguły sortowania ciągów są różne.


EDIT: jest jakaś ulga z tego problemu w .NET 4.5, obsługuje nową statyczną CultureInfo.DefaultThreadCurrentCulture i właściwości DefaultThreadCurrentUICulture.


EDIT2: kultura płynie zgodnie z opisem w czwartym akapicie w .NET 4.6. To powinno złagodzić wszystkie obawy.

2

Klamki okien są same w sobie. Nigdy nie powinieneś używać uchwytu okna (dla okna najwyższego poziomu, kontrolki podrzędnej itp.) W kontekście innego wątku, ponieważ kod implementujący obsługę okien (GDI) nie jest bezpieczny dla wątków. Ponieważ UICulture jest specyficzne dla okna, oznacza to, że staje się on również zdefiniowany na poziomie wątku.

Inne aspekty GUI są również zależne od wątku, takie jak aktywne okno i fokus. Chociaż istnieje interfejs API, nie pamiętam nazwy, która łączy kontekst UI z różnych wątków, dzięki czemu fokus, aktywne okno jest współużytkowane przez wiele wątków interfejsu użytkownika.

6

Zrobię zdjęcie - może dlatego, że potrzebujesz wielu równoczesnych nitek przy użyciu różnych kultur? Jeśli myślisz o wielojęzycznej stronie asp.net, nie chcesz, aby proces był powiązany z jednym językiem ... żądanie internetowe może być EN-US i innym fr-FR.

2

CurrentCulture to nic innego jak odniesienie do CultureInfo, więc niewiele można stracić, pozwalając, aby zawiesił się na wątku (tylko pamięć dla jednego odniesienia). Jednocześnie zyskujesz możliwość umożliwienia użytkownikom precyzyjnego kontrolowania aktualnej kultury w każdym wątku - co okazuje się ważne w niektórych aplikacjach.

Jedną z przyczyn posiadania tego drobnoziarnistego może być bardziej oczywiste dla nie-anglojęzycznych użytkowników nowoczesnego oprogramowania. Muszę regularnie przełączać klawiaturę w systemie Windows i mogę to łatwo zrobić za pomocą jednego globalnego skrótu klawiaturowego. Posiadanie CultureInfo w wątku pozwala nam łatwo implementować podobną logikę w naszych aplikacjach .NET bez konieczności zmiany tych informacji dla każdego procesu.

przykłady wykorzystania, które przychodzą do głowy:

  1. może chcę skrót, który będzie zmienić kulturę w moim programie na krótki okres czasu na żądanie dla bieżącego użytkownika (wiele zastosowań potrzebne, aby umożliwić kilka użytkownicy na tej samej stacji roboczej iw tej samej sesji). Ale ten sam proces może nadal wymagać używania domyślnej informacji kulturowej na maszynie do np. loguj zawsze z tym samym formatem datownika.

  2. Możliwe, że masz również rozwiązanie do raportowania, które mogłoby wyświetlać raporty dla kilku oddziałów globalnej firmy, każda w swojej własnej kulturze. Twój projekt byłby mniej ograniczony, gdybyś mógł zmienić CultureInfo dla każdego wątku.

  3. Innym powodem byłoby, gdybyś chciał napisać do pliku przy użyciu określonej kultury, ale nie chciałbyś określać kultury w swoich funkcjach zapisu (np. Ponieważ funkcje te zostały już zapisane). Wtedy możesz łatwo zmienić tę logikę, nie zmieniając jej na inne wątki, które mogą wykonywać pracę wymagającą domyślnej kultury.

Powiązane problemy