2010-09-13 2 views

ответ

8

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

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

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

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


UPDATE: как отмечает Томас, решение будет доступно в .NET 4.5, он имеет новое свойство для класса CultureInfo, чтобы установить культуру AppDomain по умолчанию. MSDN docs are here. Точное взаимодействие с неуправляемыми потоками, которые вводят управляемый код, не совсем ясны из документации, обязательно проверьте это, если вы когда-либо позволяли встроенному коду делать обратные вызовы, например, через pinvoke, Marshal.GetFunctionPointerForDelegate() или событие COM-объекта.


UPDATE2: это было изменено снова в .NET 4.6, культура теперь течет из одного потока в другой, так что противные виды отказов заботятся. Прочтите сведения об этом в статье MSDN для CultureInfo.CurrentCulture. Вы должны явно указать 4.6 для получения выгоды.

+1

Согласно [этой странице] (http://msdn.microsoft.com/en-us/library/ms171868%28v=vs.110%29.aspx), это возможно в .NET 4.5: «Возможность определять культуру для домена приложения». Однако я не нашел, как это сделать ... Я не вижу никакого соответствующего свойства в AppDomain или AppDomainSetup –

+0

@ Томас: см. Валдис [ответ] (http://stackoverflow.com/a/8030336/107604) ниже. –

3

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

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); 
+0

хорошее решение ... но мимо цели - мне нужно что-то, что будет установлен культура, даже когда я забываю ее установить. То же самое может произойти здесь, если я забуду начать поток через метод «StartThread». Я хочу, чтобы все потоки автоматически наследовали свою культуру. – Nissim

+0

Точно. Можете ли вы показать мне фрагмент для этого? – Nissim

Смежные вопросы