c# - Enum.TryParse - 它是线程安全的吗?

标签 c# .net .net-4.0 enums tryparse

我想弄清楚 .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/

相关文章:

regex - 用正则表达式检查变音符号

c# - 像 c++ 中的 c# 参数一样吗?

c# - 从仅系统托盘的应用程序创建工具提示

c# - C# 方法可以定义可变数量的对象参数和可变数量的整数参数吗?

.net - 将角色分配给私有(private)应用程序中的客户端 key

.net - WCF 中存储的默认协议(protocol)映射在哪里

c# - 为什么我不能在带有丢弃参数的 lambda 中使用丢弃参数?

c# - BigInteger阶乘的并行计算

c# - 在没有文件下载对话框的情况下在 WebBrowser 控件中打开 office 文档?

c# - ThreadPool.QueueUserWorkItem 是线程安全的吗?