2009-04-13 51 views
9

是否有一種簡單的方法通過線程安全接口訪問基於System.Configuration的自定義配置數據,而不需要每個執行上下文來加載/重新加載配置信息,這在計算上會很繁瑣?線程安全地使用System.Configuration

System.Configuration類,像大多數(全部?)其他類微軟的.Net庫文件中,被標註有下列線程安全的信息:

任何公共靜態(在Visual Basic中的Shared)成員這種類型是線程安全的。 任何實例成員不保證是線程安全的。

通過我的這個閱讀,ConfigurationSection對象從ConfigurationManager.GetSection(string)和其他類似的方法(例如OpenExeConfiguration(string exePath).GetSection(string))不能被認爲是線程安全返回,因此不應由多個執行環境中使用。這禁止將ConfigurationSection存儲在一個本來是線程安全的單例中,因爲雖然對section對象的訪問可能是安全的,但對象上的成員本身並不安全。

然而,多次調用GetSection可能需要重新解析配置文件並分配新的ConfigurationSection實例,這些實例的開銷很高,因爲配置在初始化後可能不會改變。此外,將配置數據複製到已經成爲線程安全的另一個對象似乎打破了首先使用內置配置包的主要優點之一(可輕鬆訪問類型轉換和驗證的配置信息,而不需要太多的樣板文件碼)。

那麼,有沒有辦法使用System.Configuration線程安全的方式,而不訴諸多餘的解析和配置節的分配?即使您通過System.Configuration接口訪問它,執行自己的ConfigurationSection是否使您免於提供由Microsoft提供的擔保(如果是這樣,您將如何在訪問基礎ConfigurationSection的索引器時將其實施爲線程安全的是否需要訪問配置的數據)?

回答

5

從GetSection返回的實例不是線程安全的。這意味着您需要添加鎖定代碼才能在單例中使用它。

多次調用不會重新解析文件,除非文件已更改。數據緩存在內存中。

您的線程安全問題很容易通過使用鎖定解決(我不確定您需要,除非您在運行時更改配置),並且沒有性能問題。

+0

我一直有一個IIS服務器過去5個月隨機崩潰,因爲這一點。不知道爲什麼(崩潰是MSCorLib中的堆棧溢出),直到它發生在我的開發機器上,並且appsettings調用導致了它。我認爲這回答了我的問題。謝謝。 – 2013-08-22 20:58:03

0

ConfigurationManager.GetSection(string)是一個公共靜態成員,並且由於msdn聲明'此類型的任何公共靜態(Visual Basic中的Shared)成員都是線程安全的',因此可以認爲使用它是安全的。

至於性能,我會願意假設MS已經使它非常高效,只是使用它們的功能。請記住:過早優化是邪惡的根源。