Культура BackgroundWorker C#

Я хотел бы установить культуру для своего целого приложения. Я попробовал следующее:

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(wantedCulture);
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(wantedCulture);
Application.CurrentCulture = CultureInfo.CreateSpecificCulture(wantedCulture);

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

Какие-либо идеи установить культуру для целого приложения?

19
задан Henk Holterman 5 March 2010 в 10:29
поделиться

3 ответа

ПРИМЕЧАНИЕ: датированный материал, обязательно прочтите «Обновление» внизу, чтобы узнать об изменениях в .NET 4.6

Да, это обычный запрос, но он недоступен. Windows всегда инициализирует поток ОС с использованием системного идентификатора LCID по умолчанию, настроенного в апплете «Язык и региональные стандарты» на панели управления. Вы можете переопределить это, если сами создаете потоки. Но это непрактично для потоков пула потоков и потоков, которые могли быть созданы каким-то неуправляемым кодом, выполняющим ваш процесс, например COM-сервером.

Последний случай представляет собой проблему. .NET не имеет проблем с запуском управляемого кода в потоках, созданных неуправляемым кодом. Но он ничего не может сделать с инициализацией потока. Это верно для CurrentUICulture, но также и для более непонятных вещей, таких как Thread.SetApartmentState (). Не стоит недооценивать вероятность того, что такой поток запускает код в вашей программе, COM-серверы, написанные Microsoft, очень ориентированы на потоки.

Вам нужно будет проработать свой код зубчатой ​​гребенкой и найти любой код, который может выполняться в потоке, который вы не создавали. Любой обработчик событий является подозрительным, как и любой метод BeginXxx (), у которого есть обратный вызов. BackgroundWorker - определенно меньшая проблема.

Отсутствие переопределения культуры потока может привести к очень очень тонким и трудно диагностируемым ошибкам. Хорошим примером может служить SortedList, который содержит ключи в строке. При запуске с неправильной культурой случайным образом не удается найти элементы, которые действительно присутствуют в списке. Причина в том, что список больше не сортируется в другой культуре с другими правилами сопоставления.

Если мне удавалось достаточно вас напугать, то я передал свое сообщение. Это случилось со мной при отладке проблемы с очень большой программой, которая неправильно работала на датской машине. У нас не было датской локализации, и пользовательский интерфейс был вынужден работать на английском языке. Рабочий поток использовал красно-черное дерево, в котором в качестве ключа была строка. Когда его попросили разобраться с Åardvårks, он случайно потерпел неудачу. У меня ушла неделя.


Обновление: эта проблема устранена в .NET 4.5. Класс CultureInfo теперь имеет DefaultThreadCurrentCulture и DefaultThreadCurrentUICulture. Если он установлен, он будет использоваться для инициализации культуры любого управляемого потока вместо культуры системы Windows по умолчанию. Мне еще не ясно, как именно он взаимодействует с потоками, которые были запущены собственным кодом и вводят управляемый код.


Обновление: эта проблема была решена более тщательно в .NET 4.6. Культура сейчас течет автоматически, идеальное поведение. Об этом говорится в статье MSDN для CultureInfo.CurrentCulture () . Предоставленная информация пока что сбивает с толку, экспериментально она также передается объекту Thread, а не только потоку Task или threadpool, а DefaultThreadCurrentCulture не используется. Два шага вперед, один шаг назад, рекомендуется тестирование.

35
ответ дан 30 November 2019 в 03:33
поделиться

Моим решением было иметь центральное свойство культуры (Application.CurrentCulture - per-thread) и устанавливать текущую культуру потока в это свойство в начале рабочего потока. Система заданий помогает в этом, поскольку вы можете легко выполнять общий код до и после рабочего элемента, а класс системы заданий может хранить культуру, доступную для его заданий, так что вам не нужны глобальные файлы.

1
ответ дан 30 November 2019 в 03:33
поделиться

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

0
ответ дан 30 November 2019 в 03:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: