Я создаю службу Windows, которая запускает несколько потоков. Могу ли я установить культуру всего моего приложения, вместо того, чтобы устанавливать его в каждую нить отдельно?Определить культуру для всего appdomain
ответ
Это не возможное. Потоки получают культуру по умолчанию, когда 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 для получения выгоды.
Вы могли бы иметь собственный метод, который будет срабатывать потоки и установить культуру автоматически:
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);
хорошее решение ... но мимо цели - мне нужно что-то, что будет установлен культура, даже когда я забываю ее установить. То же самое может произойти здесь, если я забуду начать поток через метод «StartThread». Я хочу, чтобы все потоки автоматически наследовали свою культуру. – Nissim
Точно. Можете ли вы показать мне фрагмент для этого? – Nissim
Для 4,5 стандартных культур домена приложение может быть установлено через CultureInfo
класс:
Это новый правильный ответ. – Gleno
- 1. Как определить текущую культуру исполняемого потока?
- 2. Как определить глобальный регистратор для всего приложения?
- 3. Как определить некоторые константы для всего проекта?
- 4. Где лучше всего определить валидацию для поля?
- 5. AppDomain Разгрузочное убийство Parent AppDomain
- 6. Установите новую культуру для Microsoft.Speech.Recognition.SpeechRecognitionEngine
- 7. Установить культуру для asp.net RangeValidator
- 8. Укажите культуру для применения C#
- 9. Как правильно определить культуру пользовательского браузера в asp.net mvc
- 10. Delphi Unicode Определить культуру независимо от пользовательских настроек
- 11. Получить AppDomain объекта
- 12. Restart appdomain для каждого теста
- 13. Использование AppDomain для загрузки сборки
- 14. Найти appdomain для объекта MarshalByRef
- 15. Как я могу определить, сколько памяти потребляется .Net Appdomain?
- 16. Как получить строку RESX, пройдя культуру, не используя культуру потока
- 17. Как определить, работает ли код под ASP.Net или обычный AppDomain
- 18. Как указать пользовательскую культуру?
- 19. AppDomain изоляция
- 20. Изменить текущую культуру?
- 21. Как изменить культуру?
- 22. Изменить культуру приложения Silverlight
- 23. AppDomain UnhandledException
- 24. Как использовать культуру для изменения формата DATETIME
- 25. Как изменить культуру для kendo numericTextBox
- 26. Установить культуру для WPF DateTimePicker validation
- 27. C# Установить определенную культуру для класса
- 28. Заставить культуру команды консоли
- 29. Изменить системную культуру
- 30. изменить культуру используя wpflocalizeextension
Согласно [этой странице] (http://msdn.microsoft.com/en-us/library/ms171868%28v=vs.110%29.aspx), это возможно в .NET 4.5: «Возможность определять культуру для домена приложения». Однако я не нашел, как это сделать ... Я не вижу никакого соответствующего свойства в AppDomain или AppDomainSetup –
@ Томас: см. Валдис [ответ] (http://stackoverflow.com/a/8030336/107604) ниже. –