2012-04-10 101 views
5

我在和一位朋友进行辩论,他指出静态构造函数可以让位给竞态条件,因为静态构造函数可以被多次调用。看来这只能发生在高容量多线程环境中。这甚至有可能吗?c#静态构造函数中的竞态条件

我找不到任何文件证明他错了。有没有人有这方面的见解?

谢谢!

+0

竞争状态来,如果一个新的线程做一些事情,而静态构造函数已经在另一个线程运行,将触发静态构造函数。该线程将阻塞,直到静态构造函数完成运行。但静态构造函数可能正在等待该新线程完成。请参阅http://stackoverflow.com/a/8883117/385844 – phoog 2012-04-10 21:41:08

回答

3

每个AppDomain只调用一次静态构造函数。
ECMA-335规定,CLI应保证:

“A型初始化应恰好一次,任何给定类型, 除非用户代码显式调用执行。”

我还没有听说过一种方便的方法来在C#中调用类型初始值设定项。

如果您在类型初始值设定项之间创建循环依赖关系,则只能遇到问题。
在这里看到关于该问题的一篇有趣的文章:
https://msmvps.com/blogs/jon_skeet/archive/2012/04/07/type-initializer-circular-dependencies.aspx

+0

完美!谢谢您的帮助。 – webber 2012-04-11 02:12:18

+0

您应该知道,列表和列表是两种不同的类型。因此,List 的静态构造函数将被调用两次,例如。 – 2012-04-11 04:37:13

+2

@AenSidhe因为它们是不同的类型,它不是相同的静态构造函数。一旦将类型参数(如int或string)应用于List ,就会创建一个封闭类型。不同的类型也有自己的一组静态变量。打开类型列表的静态构造函数将不会被调用。有关更多信息,请参见[C#规范](http://download.microsoft.com/download/3/8/8/388e7205-bc10-4226-b2a8-75351c669b09/CSharp%20Language%20Specification.doc)的第4.4.2节。信息。 – Botz3000 2012-04-11 06:36:25

12

这可能吗?

不可以.CLR会为您处理此问题,并防止多次调用静态构造函数。

这是在C#语言规范中拼写出来的。例如,第3.1节指出:

类型的静态构造函数每个应用程序域至多运行一次。

+1

这是不正确的。埃里克举了一个如何在这里的例子:http://stackoverflow.com/a/9792537/351385 – Tergiver 2012-04-10 21:51:21

+3

@Tergiver我正在解决OP的声明“可以让位给竞争条件,因为静态构造函数可以被多次调用” - 它总是可以在任何地方以任何代码创建自己的竞赛条件。没有线程安全保证,但是规范确保静态构造函数只会被调用一次,所以*特定的竞争条件*潜力不存在。 – 2012-04-10 21:55:57

+1

但问题是,“是否可以多次调用cctor?”答案是,“是的,它*是*可能的。”只有当你从cctor本身发起呼叫时才有可能,但实际上这是可能的。 – Tergiver 2012-04-10 21:59:53