Eric Lippert和Neal Gafter C#拼图

这个难题是在2010年NDC展会上展示的。从那里有video的链接,但是它们都被破坏了。 我不明白这个scheme的行为。 为什么它挂起?

class Woot { private static float PI; private static bool initialized = doInitialize(); private static bool doInitialize() { if (!initialized) { var thread = new Thread(() => { PI = 3.14f; }); thread.Start(); thread.Join(); // here } return true; } public static void Main(string[] args) { Console.WriteLine(PI); } } 

这个程序的输出是什么? 是吗:

  • 3.14
  • 0
  • 引发exception
  • 以上都不是

我认为这个问题是由静电场发生器引起的。 我发现只有在doInitialize完成时才启动新线程(尽pipethread.Start() ) – 所以我想CLR会阻止其他线程来避免并发访问/双字段初始化

综上所述 :新创build的线程不是由CLR启动的,以避免并发访问,而主要的线程线程等待子线程完成意味着死锁

编辑

@塞巴斯蒂安(在评论中)提出了可能certificate我的理论的链接: http : //blogs.msdn.com/b/pfxteam/archive/2011/05/03/10159682.aspx

doInitialize在构造静态types时执行,然后暂停,直到设置PI的线程终止。

试图设置PI的线程在初始化之前不能运行,只有在初始化(静态构造函数和静态初始化函数)完成之后才会发生,而这些还没有像上面那样发生。

所以程序死锁。

另请参阅Eric Lippert的答案 。

线程永远不会完成,所以thread.Join()将永远不会返回。 doInitialize()是从静态构造函数中执行的。 在静态构造函数中,我们试图设置静态属性,但除非静态构造函数完成,否则我们无法访问静态属性。 种族