2012-04-10 109 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