Определить культуру для всего приложения - PullRequest
6 голосов
/ 13 сентября 2010

Я создаю службу Windows, которая запускает несколько потоков. Могу ли я установить культуру всего моего домена приложений вместо того, чтобы устанавливать его для каждого потока отдельно?

Ответы [ 3 ]

16 голосов
/ 07 ноября 2011

Для 4.5 по умолчанию культура доменов приложения может быть установлена ​​через CultureInfo класс:

8 голосов
/ 13 сентября 2010

Это невозможно. Потоки получают свою культуру по умолчанию, когда Windows создает поток, инициализированный из языкового стандарта системы по умолчанию, настроенного в Control Panel + Region and Language. Соответствующими функциями Win32 API являются Get / SetThreadLocale ().

В CLR нет механизма для наполнения потока другим значением по умолчанию. Распространенным сценарием для потока является запуск жизни, созданной неуправляемым кодом, и запуск большого количества этого неуправляемого кода, иногда делая обратный вызов в управляемый код. Этот управляемый код будет работать с Thread.CurrentCulture, установленным на культуру, выбранную неуправляемым кодом. Или Windows по умолчанию, если неуправляемый код не вызывал SetThreadLocale (). Изменение CLR может привести к не диагностируемому сбою в неуправляемом коде.

Конечно, вы можете переопределить это явно, но это трудно понять правильно. Тонкие ошибки форматирования достаточно легко увидеть, они становятся сложными, когда вы используете, скажем, структуры данных, которые неявно полагаются на порядок сортировки строк. SortedList внезапно не может найти элемент в списке, который на самом деле присутствует. Управлять им тоже сложно, множество маленьких обратных вызовов потоков в .NET Framework.

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


ОБНОВЛЕНИЕ: как отметил Томас, решение будет доступно в .NET 4.5, у него есть новое свойство для класса CultureInfo для установки культуры по умолчанию для домена приложения. Документы MSDN здесь . Точное взаимодействие с неуправляемыми потоками, которые вводят управляемый код, не очень понятно из документации, обязательно отметьте это, если вы когда-нибудь разрешите нативному коду выполнять обратные вызовы, например, через pinvoke, Marshal.GetFunctionPointerForDelegate () или событие объекта COM.


ОБНОВЛЕНИЕ2: это снова изменилось в .NET 4.6, теперь культура перетекает из одного потока в другой, поэтому заботятся о самых отвратительных режимах сбоев. Подробнее об этом читайте в статье MSDN для CultureInfo.CurrentCulture. Чтобы получить преимущество, вы должны четко указать цель 4.6.

3 голосов
/ 13 сентября 2010

У вас может быть собственный метод, который будет запускать потоки и автоматически устанавливать культуру:

static bool StartThread(WaitCallback callback, object state)
{
    return ThreadPool.QueueUserWorkItem(s =>
    {
        // Set the culture
        Thread.CurrentThread.CurrentCulture = new CultureInfo("es-ES");
        // invoke the callback
        callback(s);
    }, state);
}

А когда вам нужно запустить новый поток, просто используйте этот метод:

StartThread(state => { /** Do some processing on a new thread **/ }, null);
...