Ленивая инициализация синглтона с параметрами

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

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

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, миллисекунды Timeout как UInt32, hasThreadAffinity как логическое значение, exitContext как логическое значение) AddinExpress.RTD.2005.dll: N 00000 (0x0) JIT System.Threading.WaitHandle.InternalWaitOne(waitableSafeHandle как SafeHandle, миллисекунды Timeout как Int64, hasThreadAffinity как логическое значение, exitContext как логическое значение) AddinExpress.RTD.2005.dll: N 0020 (0x14) IL System.Threading выходное окно, время выхода из строя (WAitHandle.WaitTime) Boolean)

Что я делаю не так?

1 ответ

Решение

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

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

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

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

Обычно я использую Lazy для реализации синглетонов, но это не очень полезно, если конструктор вашего синглтона требует параметры, передаваемые в точке доступа вашего синглтона.

Другие вопросы по тегам