CultureInfo поток безопасности

У меня есть многопоточное приложение, которое анализирует некоторый текст, и ему нужно использовать информацию о английской культуре для анализа чисел из этого текста. Поэтому я не хочу создавать EngCulture каждый раз, когда вызываю функцию синтаксического анализа. В настоящее время я передаю EngCulture в качестве параметра, но меня это не устраивает. Я хочу определить EngCulture как статический член, чтобы он был доступен для потоков.

В документации Msdn говорится, что "Любые открытые статические (Shared в Visual Basic) члены этого типа являются поточно-ориентированными. Любые члены экземпляров не гарантируют поточно-ориентированные". Я просто использую следующую функцию, так как я могу узнать, использует ли TryParse какие-либо экземпляры членов EngCulture или нет?

public static CultureInfo EngCulture = new CultureInfo("en-US", false);

void parser()
{
    if (int.TryParse(value, NumberStyles.Number, EngCulture, out num))...
}

5 ответов

Решение

Попробуй использовать CultureInfo.GetCultureInfo("en-US") который "извлекает кэшированный экземпляр культуры только для чтения с использованием указанного имени культуры".

http://msdn.microsoft.com/en-us/library/yck8b540.aspx

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

private static CultureInfo _culture = CultureInfo.ReadOnly(new CultureInfo("en-US"));

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

public static CultureInfo EngCulture = CultureInfo.ReadOnly(
    new CultureInfo("en-US", false));

Вы можете установить CultureInfo определенной темы с помощью System.Threading.Thread.CurrentThread.CurrentCulture = myCI;поэтому вам не нужно передавать его каждый раз, когда вы вызываете функцию.

Обратите внимание, что простой доступ к получателям из нескольких потоков в большинстве случаев не принесет никакого вреда, если вы не измените объект.

"Члены" означают методы плюс операторы плюс поля плюс свойства. Вы используете экземпляр экземпляра и поэтому должны использовать lock или найти альтернативный способ сделать это.

Надеюсь, это поможет!

Два момента:

я не хочу создавать EngCulture каждый раз, когда вызываю функцию синтаксического анализа

Я не думаю, что это на самом деле будет слишком большой проблемой - CultureInfoОни не будут особенно большими, а что касается производительности, "встроенные" на самом деле кэшируются, поэтому все new делает это извлечь существующий объект. Во что бы то ни стало профиль и посмотреть, если это на самом деле проблема...

как я могу узнать, использует ли TryParse какие-либо экземпляры членов EngCulture или нет?

Я был бы очень удивлен, обнаружив метод, который принял CultureInfo а затем продолжил, чтобы изменить это CultureInfo в любом случае. Хотя они на самом деле не являются формально неизменяемыми, я бы использовал их (особенно "встроенные"), как если бы они были неизменяемыми, не задумываясь.

Итак, я бы сказал, есть статический new CultureInfo("en-US", false) и передать его - ничто не поменяет его, поэтому проблемы с многопоточностью не возникают.

Другие вопросы по тегам