C#中静态初始化程序的线程安全性

Meh*_*dad 5 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 new object */ }
}
Run Code Online (Sandbox Code Playgroud)

C#保证以下哪一项MyStaticClass.myField尚未初始化?

  1. 如果线程1和2尝试一起访问myField(按此顺序),GetNewObject则在线程2读取之前将开始执行myField.

  2. 如果线程1和2尝试一起访问myField(按此顺序),GetNewObject则在线程2读取之前将完成执行myField.

一般来说CLR怎么样:如果它的保证与C#不同,它们在哪些方面有所区别?
在更新版本的.NET框架中是否更改了行为?

注意:

这是一个棘手的问题,我认为完整的答案可能会提到静态构造函数和静态初始化程序之间的区别,以及它们如何交互beforefieldinit以产生声明的结果.

Han*_*ney 3

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

http://msdn.microsoft.com/en-us/library/aa645612(v=vs.71).aspx

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

请参阅 Eric Lippert 的回复:/sf/answers/657931921/并注意“cctor”是静态构造函数的 IL。

没有任何 cctor 直接或间接调用 MyMethod!现在是否有可能在 MyClass 的 cctor 完成之前调用像 MyMethod 这样的静态方法?

不。

即使涉及多个线程,情况仍然如此吗?

是的。cctor 将在一个线程上完成,然后才能在任何线程上调用静态方法。

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

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