Безопасность потолка CultureInfo

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

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

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

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

Ответ 1

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

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

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

Две точки:

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

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

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

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

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