Почему CurrentCulture является собственностью Thread? - PullRequest
7 голосов
/ 14 ноября 2010

Мне кажется странным, что выбор текущей информации о культуре (CurrentCulture и / или CurrentUICulture) является свойством запущенного потока.По крайней мере, кажется, что объем такой вещи должен быть на один уровень выше, на уровне процесса.

Но эти вещи обычно имеют смысл, когда вы слышите обоснование.Может быть поучительно выяснить, почему разработчики .NET решили, что Thread является подходящим местом для размещения этого свойства.

Ответы [ 4 ]

10 голосов
/ 14 ноября 2010

Для начала, это был не совсем их выбор.Это решение было принято задолго до того, как они начали, культура - это свойство потока операционной системы.Посмотрите, например, документы SDK для API-функций Get / SetThreadLocale ().

Это не полностью объясняет это, они виртуализировали другие функции ОС, хотя эта * очень жесткаявиртуализировать, потому что очень много API-интерфейсов чувствительны к культуре, особенно COM.

Следующая веская причина в том, что изменение всего процесса культуры очень сложно реализовать.Это неразрешимое состояние гонки.Какой-то другой поток вполне может быть в середине форматирования данных, имеющих сходство с культурой.В то время как блокировка будет работать для предотвращения использования свойств культуры точно так же, как она изменяется, она может не предотвращать ее изменение в середине цепочки вызовов форматирования.Это потребовало бы, чтобы они взяли некоторую глобальную блокировку и держали ее в течение всего времени работы форматирования.Вероятность тупика очень вероятна.

Есть еще один аспект, который, я думаю, является реальной проблемой.Это связано со свойством Thread.ExecutionContext.Каркас использует это для «передачи» состояния потока из одного потока в другой.Очень непонятно, но важно внедрить такие вещи, как контекст безопасности, в рабочий поток.Было бы идеально, если бы этот контекст мог также наполнить культуру, чтобы вы могли быть уверены, что любой из рабочих, с которыми вы начинаете работать, имеет ту же культуру, которую вы выбрали, а не операционную систему по умолчанию.

Это не так,Я действительно не знаю почему.Вероятно, потому что самая первая причина, которую я дал.Это делает однако делает очень опасным изменение культуры потока.Виды ошибок, которые могут вызывать очень тонкие.Как создание SortedDictionary со строкой в ​​качестве ключа в главном потоке с культурой по умолчанию не операционной системы.Затем выясняется, что рабочий поток больше не может время от времени находить материал, потому что правила сортировки строк отличаются.


РЕДАКТИРОВАТЬ: в .NET 4.5 есть некоторая облегчение этой проблемы, он поддерживает новую статическуюСвойства CultureInfo.DefaultThreadCurrentCulture и DefaultThreadCurrentUICulture.


EDIT2: культура теперь работает, как описано в 4-м абзаце в .NET 4.6.Это должно облегчить все проблемы.

6 голосов
/ 14 ноября 2010

Я сделаю снимок - может быть, потому что вам понадобится несколько одновременных потоков с использованием другой культуры?Если вы думаете о многоязычном веб-сайте asp.net, вы не хотите, чтобы процесс был привязан к одному языку ... веб-запрос может быть EN-US и другим fr-FR.

2 голосов
/ 14 ноября 2010

CurrentCulture - это не что иное, как ссылка на CultureInfo, поэтому немало бы потеряло, если бы оно зависало в потоке (только память для одной ссылки). В то же время вы получаете возможность разрешить пользователям точно контролировать текущую культуру для каждого потока, что оказывается важным в некоторых видах приложений.

Одна из причин такого мелкого размаха может быть более очевидной для не говорящих по-английски пользователей современного программного обеспечения. Мне, например, приходится регулярно переключать клавиатуру в Windows, и я могу легко это сделать одним глобальным сочетанием клавиш. Наличие CultureInfo в потоке позволяет нам легко реализовать аналогичную логику в наших приложениях .NET без необходимости изменять эту информацию для каждого процесса.

Примеры использования, которые приходят на ум:

  1. Я мог бы хотеть ярлык, который изменит культуру в моей программе на короткий период времени по запросу для текущего пользователя (во многих приложениях необходимо разрешить нескольким пользователям на одной рабочей станции и в одном сеансе) Но этот же процесс, возможно, придется продолжать использовать CultureInfo по умолчанию на компьютере, например, для Журнал всегда с тем же форматом отметки времени.

  2. У вас также может быть решение для отчетов, которое будет отбрасывать отчеты для нескольких филиалов глобальной компании, каждая в своей культуре. Ваш дизайн будет менее ограничен, если вы сможете изменить CultureInfo для потока.

  3. Другая причина может быть в том, что вы хотите записать в файл с использованием определенной культуры, но не хотите указывать культуру в ваших функциях записи (например, потому что эти функции уже написаны). Тогда вы сможете легко изменить эту логику, не меняя ее в других потоках, которые могут выполнять работу, требующую культуры по умолчанию.

2 голосов
/ 14 ноября 2010

Оконные ручки сами по себе являются нитями.Никогда не следует использовать дескриптор окна (для окна верхнего уровня, дочернего элемента управления и т. Д.) В контексте другого потока, поскольку код, реализующий обработку окна (GDI), сам по себе не является поточно-ориентированным.Поскольку UICulture является специфичным для окна, это означает, что оно также становится определенным на уровне потока.

Другие аспекты графического интерфейса также зависят от потоков, таких как активное окно и фокус.Несмотря на то, что есть API, я не могу вспомнить имя, которое объединяет контекст пользовательского интерфейса из разных потоков, так что основное окно, активное окно, совместно используется несколькими потоками пользовательского интерфейса.

...