2012-03-31 4 views
2

Я пытаюсь создать singleton, который имеет непустой конструктор и получить доступ к нему синхронно: поскольку я не контролирую порядок инициализации моего компонента, если компонент доступ к синглтону перед его инициализацией, он должен ждать.Lazy инициализация singleton с параметрами

Фабричный метод вызывается только один раз, и моя фаза initilization бросает исключение

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, иногда я получаю следующее:

Exception Источник: mscorlib Тип исключения: System.Runtime.InteropServices.SEHException Сообщение исключения: Внешний компонент бросил исключение. Исключение Цель сайта: WaitOneNative

---- Трассировка стека ---- System.Threading.WaitHandle.WaitOneNative (waitableSafeHandle Как SafeHandle, millisecondsTimeout Как UInt32, hasThreadAffinity As Boolean, exitContext As Boolean) AddinExpress.RTD. 2005.dll: N 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 (миллисекундыTimeout As Int32, exitContext As Boolean)

W шляпа, я делаю неправильно?

ответ

4

Вы не создали подходящий синглтон. Правильный синглтон должен иметь статический метод для доступа к нему и частный конструктор.

Другая проблема заключается в том, что если у вас есть параметры, с помощью которых можно инициализировать синглтон, что это значит, если вы инициализируете singleton более одного раза разными параметрами? Это ошибка?

Предполагая, что вы можете просто игнорировать несколько инициализацый с различными параметрами, можно реализовать следующим образом (но я думаю, что вы можете иметь конструкторскую недоработку где-то):

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(); 
} 

Я обычно использую ленитесь реализовать одиночек, но это не так полезно, если ваш конструктор singleton требует параметров, переданных в точке доступа вашего синглтона.

+0

Извините ... Что я хочу сделать, так это то, что я инициализирую синглтон с параметрами из одной точки в моем коде (при запуске). Однако из-за порядка инициализации компонентов Excel (например, при запуске Excel двойным щелчком по электронной таблице) сначала могут быть инициализированы другие компоненты и попытаться получить доступ к синглтону. Я хочу, чтобы они подождали, пока основной компонент не инициализирует singleton ... – Edmondo1984

Смежные вопросы