2012-03-31 73 views
2

我想創建一個具有非空構造函數的單例,並將其存入一個同步的方式:因爲我沒有控制我的組件的初始化順序,如果一個組件在初始化之前訪問單例,它必須等待。帶參數的單例的惰性初始化

工廠方法被調用一次就好了,我動初始化階段拋出一個異常

private static volatile GottwareExcelAddin _instance; 
private static readonly ManualResetEvent InitializedEvent=new ManualResetEvent(false); 

    internal static Singleton CurrentInstance 
    { 
     get 
     { 
      InitializedEvent.WaitOne(); 
      return _instance; 
     } 
    } 

    #endregion 

    private Singleton(String url, Int otherstuff) 
    { 
     // do stuff 
     InitializedEvent.Set(); 
    } 


    #region public factory 
    [OnWorkerThread] 
    public static void Singleton(String spaceUrl, _Application excelApp) 
    { 
     if (_instance == null) 
      _instance = new Singleton(spaceUrl, excelApp); 
    } 

的[OnWorkerThread]是使一個工作線程工廠運行的屬性,工廠只調用一次。

當我啓動MYAPP,有時我得到如下:

異常源:mscorlib程序 異常類型:System.Runtime.InteropServices.SEHException 異常消息:外部組件發生異常。 異常目標站點:WaitOneNative

----堆棧跟蹤---- System.Threading.WaitHandle.WaitOneNative(waitableSafeHandle作爲的SafeHandle,millisecondsTimeout作爲UInt32的,hasThreadAffinity由於布爾,exitContext由於布爾) AddinExpress.RTD。 2005.dll(00000)(0x0)JIT System.Threading.WaitHandle.InternalWaitOne(waitableSafeHandle As SafeHandle,millisecondsTimeout As Int64,hasThreadAffinity As Boolean,exitContext As Boolean) AddinExpress.RTD.2005.dll:N 0020(0x14)IL System.Threading.WaitHandle.WaitOne(毫秒超時爲Int32,exitContext爲布爾值)

W我做錯了什麼?

回答

4

你還沒有在那裏創建一個合適的單身人士。一個合適的單例應該有一個靜態方法來訪問它,並有一個私有構造函數。

另一個問題是,如果你有參數來初始化一個單例,如果你用不同的參數多次初始化單例,這意味着什麼?這是一個錯誤嗎?

假設你可以忽略的多個initialisations使用不同的參數,可以按如下方式實現它(但我認爲你可能什麼地方有一個設計錯誤):

class Singleton 
{ 
    public static Singleton Instance(string param1, int param2) 
    { 
     if (_instance == null) 
     { 
      lock (_locker) 
      { 
       if (_instance == null) // Double-checked locking (works in C#!). 
       { 
        _instance = new Singleton(param1, param2); 
       } 
      } 
     } 

     return _instance; 
    } 

    private Singleton(string param1, int param2) 
    { 
     // Whatever. 
    } 

    private static Singleton _instance; 
    private static readonly object _locker = new object(); 
} 

我通常使用懶惰實現單身,但是如果你的單例的構造函數需要在你的單例訪問點傳入的參數,那麼它就沒那麼有用。

+0

對不起......我想要做的是,我用我的代碼中的一個點(啓動時)的參數初始化單例。但是,由於Excel組件的初始化順序(例如,如果通過雙擊電子表格啓動Excel),其他組件可能會先初始化並嘗試訪問單例。我希望這些要等到主要組件初始化單例... – Edmondo1984 2012-04-11 09:53:02