Статический конструктор и класс Singleton - PullRequest
21 голосов
/ 15 июля 2009

У меня есть кеш объекта, который реализует шаблон проектирования Singleton. Мой подход к синглтону всегда заключался в том, чтобы лениво загружать статический экземпляр при первом обращении к свойству.

public static Widget
{
    get
    {
        if(instance==null) instance = new Widget();
        return instance;
    }
}

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

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

public static Widget
    {
        get
        {
            if(instance==null)
            {
                lock(padlock)
                {
                    if(instance==null) instance = new Widget();
                }
            }
            return instance;
        }
    }

У меня нет большого опыта работы со статическими конструкторами, поэтому я не хочу переходить с этой идеей, если она является равной или худшей реализацией свойства lazy load.

Cheers, Gary

Ответы [ 2 ]

16 голосов
/ 15 июля 2009

У Джона Скита есть хорошая статья о одиночках, обсуждающих эту проблему.

2 голосов
/ 15 июля 2009

Вместо того, чтобы запускать собственный поточный безопасный ленивый инициализатор и возможно ошибаться, я рекомендую прочитать msdn на Lazy<T>.

https://docs.microsoft.com/en-us/dotnet/framework/performance/lazy-initialization#thread-safe-initialization

...