我想弄清楚 .NET 4.0 的 Enum.TryParse 是否是线程安全的。
源代码(反编译)是:
[SecuritySafeCritical]
public static bool TryParse<TEnum>(string value, bool ignoreCase, out TEnum result) where TEnum : struct
{
result = default(TEnum); /// (*)
Enum.EnumResult enumResult = default(Enum.EnumResult);
enumResult.Init(false);
bool result2;
if (result2 = Enum.TryParseEnum(typeof(TEnum), value, ignoreCase, ref enumResult))
{
result = (TEnum)enumResult.parsedEnum;
}
return result2;
}
对我来说似乎有问题的是这一行:
result = default(TEnum); /// (*)
如果另一个线程在将结果设置为默认值之后且在将其设置为解析值之前立即访问结果怎么办?
[编辑] 根据 Zoidberg 的回答,我想稍微改一下这个问题。
我想问题是,如果 Enum.TryParse 是“事务性的”(或原子性的)。
假设我有一个静态字段,并将其传递给 Enum.TryParse:
public static SomeEnum MyField;
....
Enum.TryParse("Value", out MyField);
现在,在执行 TryParse 时,另一个线程访问 MyField。 TryParse 会暂时将 MyField 的值更改为 SomeEnum 的默认值,然后才会将其设置为解析后的值。
这不一定是我的代码中的错误。我希望 Enum.TryParse 要么将 MyField 设置为解析后的值,要么根本不碰它,而不是将它用作临时字段。
最佳答案
result
与所有其他局部变量和参数一样,是按调用计算的。 by-ref 参数的线程安全性是一点 更复杂的描述,但是:在每个理智的用法中 - 这不会成为问题。我可以强制一个它处于危险中的场景(由于通过引用传递),但这将是一个人为的例子。
典型用法:
SomeEnumType foo;
if(Enum.TryParse(s, true, out foo)) {...}
绝对安全。
下面有点复杂:
var objWithField = new SomeType();
// thread 1:
{
Enum.TryParse(x, true, out objWithField.SomeField));
}
// thread 2:
{
Enum.TryParse(y, true, out objWithField.SomeField));
}
并且不是线程安全的,但比您在问题中描述的原因要微妙得多。
关于c# - Enum.TryParse - 它是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9533845/