C# C语言中静态初始化器的线程安全性#

C# C语言中静态初始化器的线程安全性#,c#,multithreading,thread-safety,static-initialization,C#,Multithreading,Thread Safety,Static Initialization,每个人都说静态初始值设定项是线程安全的,但我担心一个特别的细节 假设我有 static class MyStaticClass { public static readonly object myField = MyOtherClass.GetNewObject(); } static class MyOtherClass { public static object GetNewObject() { /* arbitrary code that returns a n

每个人都说静态初始值设定项是线程安全的,但我担心一个特别的细节

假设我有

static class MyStaticClass
{
    public static readonly object myField = MyOtherClass.GetNewObject();
}

static class MyOtherClass
{
    public static object GetNewObject()
    { /* arbitrary code that returns a new object */ }
}
MyStaticClass.myField
尚未初始化时,C#保证以下哪项

  • 如果线程1和2尝试同时访问
    myField
    (按该顺序),则
    GetNewObject
    将在线程2读取
    myField
    之前启动执行

  • 如果线程1和2尝试同时访问
    myField
    (按该顺序),
    GetNewObject
    将在线程2读取
    myField
    之前完成执行

  • 一般来说,CLR如何:如果它的保证与C不同,它们在哪些方面不同?
    在较新版本的.NET framework中,行为是否发生了更改

    注:
    这是一个棘手的问题,我认为完整的答案可能会提到静态构造函数和静态初始值设定项之间的区别,以及它们如何在foreFieldInit之前与
    交互以产生所声称的结果。

    案例2将得到尊重。在初始化类型之前,类字段、属性或方法无法取消引用,并且在静态构造函数完成之前,类型将不会初始化。据我所知,静态构造函数是一个阻塞调用

    “类的静态构造函数在给定的应用程序域中最多执行一次。”

    请参阅Eric Lippert的回复:“cctor”是静态构造函数的IL

    没有人直接或间接地调用MyMethod!现在有可能在MyClass的cctor完成之前调用像MyMethod这样的静态方法吗

    没有

    即使涉及多个线程,这仍然是真的吗

    对。在任何线程上调用静态方法之前,cctor将在一个线程上完成

    cctor可以被多次调用吗?假设两个线程都导致cctor运行

    无论涉及多少线程,都保证最多调用一次cctor。如果两个线程“同时”调用MyMethod,那么它们将竞争。其中一人输掉比赛并拦网,直到MyClass cctor在获胜线程上完成

    摘自:

    在第一次访问静态成员之前以及在调用静态构造函数(如果有)之前初始化静态成员


    如果第二个方法在两个不同的线程中运行,但从不使用静态类,则将永远不会构建它。但是,如果有对它的引用,它将在两个线程中的任何一个访问它之前被初始化。

    我不理解
    GetNewObject()
    的相关性?是访问另一个类中的字段的方法吗?@SimonBelanger:这没有什么意义,我只是把它放在一个单独的类中,以表明它可能是任意代码。如果答案根据定义的位置/方式而变化,那么我也想知道这一点。我并不是说静态初始值设定项是线程安全的。我说过很多次相反的话。由于静态初始值设定项中的错误而死锁的程序不是线程安全的。因此,您的开场白是错误的。它执行一次并不意味着它在第二次访问之前已经完成了执行。只有在初始化类型之前,才能进行访问,并且类型初始值设定项/构造函数只执行一次,因此,从逻辑上说,访问必须等待类型初始化,而不重复构造函数或初始值设定项逻辑。很可能初始值设定项将在第一次访问时执行一次,但如果字段尚未分配给,则第二个线程只读取
    null
    ,而不是等待初始化。你可能是对的,但你的理由并不意味着你提到的结论。啊。。。“即使涉及多个线程,这仍然是真的吗?”回答了我的问题,谢谢!我花了一点时间来确认我的理解。谢谢你的练习。:)那么#2是保证还是否定呢?哦,我刚刚理解了与
    GetNewObject
    的关系,我忽略了字段初始化是什么。是的#2。