Ленивая инициализация синглтона с параметрами
Я пытаюсь создать синглтон с непустым конструктором и получить к нему синхронизированный доступ: поскольку у меня нет контроля над порядком инициализации моего компонента, если компонент обращается к синглтону до его инициализации, он должен Подождите.
Метод фабрики вызывается только один раз, и моя фаза инициализации вызывает исключение
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 для реализации синглетонов, но это не очень полезно, если конструктор вашего синглтона требует параметры, передаваемые в точке доступа вашего синглтона.