2009-08-25 109 views
10

我正在用C#編寫WCF服務。最初,我的實現有一個靜態構造函數來執行一次性初始化,但正在完成的一些初始化可能(暫時)失敗。類型初始值設定項(靜態構造函數)異常處理

看起來靜態構造函數只被調用一次,即使第一次(失敗)嘗試引發異常?任何隨後嘗試實例化我的類都將立即失敗,並且TypeInitializationException未實際執行代碼。

C#語言規範聲明最多隻會調用一次靜態構造函數,但基本上這會導致出現一個例外,即使您捕獲它,也無法恢復該錯誤?

我在這裏錯過了什麼嗎?我想我應該將任何遠程危險的東西移動到服務的實例構造函數中,然後手動檢查類初始化是否已經成功完成了?

回答

3

所以你可以將關鍵部分包裝在try/catch中,至少這意味着類型不會失敗初始化,但是如果初始化代碼是關鍵的,那麼這種行爲實際上是好的 - 類型不是可用於這個未初始化的狀態。

另一種選擇是將它作爲單例 - 每次嘗試獲取實例時,都可以正確創建類型,直到成功爲止,即使它第一次失敗。

如果Instance在第一個(或第二個等)時間返回null,您仍然需要對調用方進行一些錯誤處理。

編輯:如果你不想單身,那麼只需要你的構造函數初始化靜態部分

例如

private object _lock = new object() 
private bool _initialized; 

public T() 
{ 
    lock(_lock) 
    { 
     if(!_initialized) 
     { 
     try 
     { 
      //Do static stuff here 
     } 
     catch(Exception ex_) 
     { 
      //Handle exception 
     } 
     } 
    } 
} 
+1

這實際上是我現在有,除了我使用一些雙重檢查鎖定和我的'_initialized'布爾是'易揮發的(不應該沒有雙重檢查鎖定是必要的) – Thorarin 2009-08-25 14:18:05

3

這裏的教訓很簡單:不要在可能合理失敗的靜態構造函數中做任何事情。

+0

MSDN提到該類型將保持未初始化,但我沒有立即採取這種做法意味着它將不可能創建一個實例。我本來希望能有更明確的警告。這不是一個巨大的解決方法,但它確實使靜態構造函數的用處不大:( – Thorarin 2009-08-25 14:13:20

+0

@ Thorarin - 僅在AppDomain的生命週期中,'type將在程序運行的應用程序域的生命週期中保持未初始化狀態'從MSDN http://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx – VoodooChild 2013-03-01 19:34:44

0

我過去使用的解決方法是創建一個Singleton。當且僅當失敗意味着整個應用程序無法運行時,使靜態構造函數失敗。

相關問題