问题 CultureInfo线程安全


我有一个解决一些文本的多线程应用程序,它需要使用英文文化信息来解析这个文本中的数字。 所以,我不想每次调用解析函数时都创建EngCulture。目前我正在通过EngCulture作为参数,但我对此并不满意。 我想将EngCulture定义为静态成员,因此它将由线程共享。

Msdn文档说“这种类型的任何公共静态(在Visual Basic中共享)成员都是线程安全的。任何实例成员都不能保证是线程安全的。” 我只是使用以下函数,所以我怎么知道TryParse是否使用EngCulture的任何实例成员?

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

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

7470
2017-07-21 11:02


起源



答案:


尝试使用 CultureInfo.GetCultureInfo("en-US") “使用指定的区域性名称检索文化的缓存,只读实例。”

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

或者让你的领域只读,这样你就不需要锁定了:

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

6
2017-07-21 11:14



是的,只读承诺使其成为线程安全的。 - Henk Holterman
是否 CultureInfo.ReadOnly 授予线程安全保障?因为 只读和线程安全是不同的。 - ta.speot.is
@ ta.speot.is:好问题。我对自己很好奇 问了一个问题。 - Heinzi


答案:


尝试使用 CultureInfo.GetCultureInfo("en-US") “使用指定的区域性名称检索文化的缓存,只读实例。”

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

或者让你的领域只读,这样你就不需要锁定了:

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

6
2017-07-21 11:14



是的,只读承诺使其成为线程安全的。 - Henk Holterman
是否 CultureInfo.ReadOnly 授予线程安全保障?因为 只读和线程安全是不同的。 - ta.speot.is
@ ta.speot.is:好问题。我对自己很好奇 问了一个问题。 - Heinzi


为了获得线程安全性,您可以使用static创建只读文化 CultureInfo.ReadOnly 方法:

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

3
2017-07-21 11:14



我在文档中找不到只读的地方 CultureInfo 是线程安全的。请参阅我对已接受答案的评论。 - ta.speot.is


您可以使用设置特定Thread的CultureInfo System.Threading.Thread.CurrentThread.CurrentCulture = myCI; 因此,每次调用函数时都不必传递它。

请注意,如果不修改对象,在大多数情况下,仅从多个线程访问getter不会造成任何伤害。


1
2017-07-21 11:16





“成员”表示方法加运算符以及字段和属性。您正在使用实例成员,因此应使用 lock 或找到另一种方法。

希望有所帮助!


0
2017-07-21 11:10





两点:

每次调用解析函数时我都不想创建EngCulture

我认为这实际上并不是太令人担忧 - CultureInfos不会特别大,至于性能,'内置'实际上是缓存的,所以全部 new 确实是检索现有对象。通过各种方式配置文件,看看它是否真的是一个问题......

我怎么知道TryParse是否使用EngCulture的任何实例成员?

发现一种方法,我会感到非常惊讶 公认 一个 CultureInfo 然后继续 更改 那 CultureInfo 以任何方式。虽然它们实际上并不是正式不可变的,但我会使用它们(尤其是“内置”的),好像它们是不可变的,没有第二个想法。

所以,我想说有一个静态的 new CultureInfo("en-US", false) 传递它 - 没有什么可以改变它,所以不会出现多线程问题。


0
2017-07-21 11:12



我犹豫是否有一些线程将它置于一个不一致的状态(在从列表等读取的中间),而另一个线程试图读取它。因此,如果从中读取并不是一个大问题,为什么他们说使用实例成员是不安全的。 - lockedscope
@lockedscope我赞赏你的谨慎。我从其他答案中学到了“内置” CultureInfos是只读的,无论如何都有一个 ReadOnly 方法,所以这些方法之一应该确保安全。 - AakashM