Можно ли установить CultureInfo для приложения .NET или просто потока? - PullRequest
23 голосов
/ 10 февраля 2010

У меня есть приложение, написанное на C #, которое не имеет GUI или UI, но вместо этого записывает файлы, которые анализируются другим приложением (в XML и других).

У меня есть клиент, у которого CultureInfo имеет NumberDecimalSeparator, установленный на запятую, что приводит к ошибкам синтаксического анализа с числами с плавающей запятой (PI будет иметь значение 3,1415 ).

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

  1. (очевидно) обычный подход установки CurrentThread.CurrentCulture в качестве первой строки в Main () , но, похоже, он сбрасывается.
  2. Вариация / расширение на http://www.codeproject.com/KB/cs/Change_App_Culture.aspx
  3. Сделайте то же самое (# 1) для явно созданных потоков в приложении.

И переход на использование явного форматирования не возможен (150K + строк, большинство написано бывшими сотрудниками).

[Изменить] Приложение привязывается к сокету и обрабатывает запросы от выделенных клиентов. В зависимости от типа запроса он порождает разные классы обработчиков.

Извините, когда я впервые опубликовал сообщение, я должен был уточнить в # 1, что ( я, хотя ) я сделал это во всех обработчиках, которые также были явно созданы.

Оказывается, я пропустил поток / обработчик, который вызывал проблему. Итак, приложение теперь работает правильно, но остается вопрос, можно ли установить культуру во всех потоках.

Если бы он мог перебирать все потоки, это тоже решило бы проблему. Итак:

Как я могу получить все Thread объектов (не ProcessThread ) в текущем процессе?

Ответы [ 4 ]

33 голосов
/ 02 июля 2012

В .NET 4.5 вы можете использовать CultureInfo.DefaultThreadCurrentCulture

14 голосов
/ 11 февраля 2010

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

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

Подход, который я успешно использовал, заключается в установке языкового стандарта в потоке запуска и последующем использовании фабрики потоков для создания потоков с «языковым стандартом приложения». Для BackgroundWorkers вы можете использовать либо фабричный, либо производный класс, так как Thread запечатан, а BackgroundWorker нет.

6 голосов
/ 10 февраля 2010

Я не думаю, что вы можете установить культуру для всего приложения, но вы можете установить экспликацию культуры, когда создаете поток:

using System;
using System.Globalization;
using System.Threading;

class Program {

    static void thread_test() {
        Console.WriteLine("Culture: {0}", CultureInfo.CurrentCulture.DisplayName);
    }

    public static void Main(params string[] args) {
        Thread t = new Thread(thread_test);
        t.CurrentCulture = new CultureInfo("it-it");
        t.Start();
        t.Join();
    }
}
3 голосов
/ 01 ноября 2010

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

...