Синглтон против кэша ASP.NET

Я создал класс реестра в .NET, который является синглтоном. По-видимому, этот синглтон ведет себя так, как если бы он хранился в кэше (объект-синглтон доступен для каждой сессии). Является ли это хорошей практикой, если я должен добавить этот синглтон в кеш? + нужно ли мне следить за проблемами параллелизма с функцией GetInstance()?

namespace Edu3.Business.Registry
{
    public class ExamDTORegistry
    {
        private static ExamDTORegistry instance;
        private Dictionary<int, ExamDTO> examDTODictionary;

        private ExamDTORegistry()
        {
            examDTODictionary = new Dictionary<int, ExamDTO>();
        }

        public static ExamDTORegistry GetInstance()
        {
            if (instance == null)
            {
                instance = new ExamDTORegistry();
            }
            return instance;
        }
    }
}

person Lieven Cardoen    schedule 19.11.2008    source источник


Ответы (6)


я бы сделал так:

частный статический экземпляр ExamDTORegistry READONLY;

тогда вам не нужно проверять NULL и его потокобезопасность.

person Community    schedule 12.02.2009

Что ж, ваш метод GetInstance определенно не является потокобезопасным — если два потока вызывают его одновременно, они вполне могут получить два разных экземпляра. У меня есть страница о реализации шаблона singleton, если это поможет.

Ваш код полагается на одноэлементность? Имейте в виду, что если AppDomain будет перезагружен, вы все равно получите новый экземпляр.

Однако я не вижу особой пользы в помещении объекта в кеш. Есть ли что-то, о чем вы думаете в частности?

person Jon Skeet    schedule 19.11.2008
comment
Да, когда AppDomain перезагружается, новый экземпляр не проблема. Но синглтон ведет себя как глобальный объект, не так ли? При тестировании я вижу, что ASP.NET не создает синглтон для каждого сеанса, а просто синглтон для всего приложения. - person Lieven Cardoen; 19.11.2008

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

person user35149    schedule 19.11.2008
comment
Это хорошая практика, когда используется в правильном месте. К сожалению, я НИКОГДА не работал там, где это действительно нужно, хотя я видел, как они реализованы сотни раз :) MonoState — хорошая альтернатива. - person Ben Scheirman; 19.11.2008
comment
Чтобы ответить на ваш вопрос, у меня есть 200 кандидатов, которые одновременно запрашивают один и тот же ExamDTO (по идентификатору). Я видел, что код на стороне сервера 200 раз обращался к базе данных, чтобы сдать экзамен. Теперь я хотел кэшировать экзамен по его идентификатору, чтобы, когда он уже был загружен, сервер больше не обращался к БД. - person Lieven Cardoen; 19.11.2008
comment
Тогда вам нужен кеш (не синглтон, опасно их путать). Одно предложение см. в комментарии Бена к MonoState. В противном случае скройте кеширование в вашем слое данных. Хорошие O/R-преобразователи, такие как NHibernate, уже поддерживают такие вещи. - person user35149; 19.11.2008
comment
Еще один вопрос (извините за беспокойство): это вызывает у вас проблемы с производительностью? Вы удивитесь, но 200 запросов на одну и ту же запись — это пустяк для большинства современных БД. Если у вас проблемы с производительностью, я полностью понимаю необходимость кеша. - person user35149; 19.11.2008
comment
Я буду честен с вами, я старший флексер, который уже полтора года пытается изучить ASP.NET. На самом деле это 200 запросов к хранимой процедуре, что довольно интенсивно. Если бы я делал это с помощью NHibernate или SubSonic, один запрос должен был бы адресовать пару записей. - person Lieven Cardoen; 19.11.2008
comment
В чем разница между кешем и синглтоном? Поведение выглядит так же... Синглтон можно вызывать из любого сеанса (это похоже на глобальную переменную). - person Lieven Cardoen; 19.11.2008
comment
Я посмотрел на MonoState и не является ли Singleton своего рода MonoState с одной статической переменной, самим экземпляром? - person Lieven Cardoen; 19.11.2008
comment
Синглтон предназначен для ограничения класса только одним экземпляром с глобальным доступом. Шаблон моносостояния — это способ, при котором несколько экземпляров имеют общее состояние. Кэш обеспечивает доступ к одному и тому же объекту несколько раз, не создавая их новых экземпляров. MonoState — это ОДИН способ реализации кеша. - person user35149; 20.11.2008
comment
Синглтон можно вызывать из любого сеанса (это похоже на глобальную переменную). И глобальные переменные ПЛОХО и НЕ являются правильным использованием шаблона синглтона. - person user35149; 20.11.2008

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

HttpContext.Application также доступен для всех сеансов и является хорошим местом для хранения постоянных объектов приложения.

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

person Greg    schedule 19.11.2008
comment
Что это за дополнительная функциональность? - person Lieven Cardoen; 19.11.2008
comment
Срок действия/удаление элементов из памяти. - person Greg; 22.11.2008

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

person Ben Scheirman    schedule 19.11.2008

Я думаю, что исходный вопрос говорил о том, что было предпочтительнее. Если у вас есть данные, которые остаются статичными или практически неизменяемыми, то HTTP-кеширование или шаблон singleton имеют большой смысл. Если синглтон загружается при запуске приложения, то проблемы с «поточностью» вообще нет. Как только синглтон будет на месте, вы получите тот же экземпляр, который вы запрашивали. Проблема со многим из того, что я вижу в реальных реализациях, заключается в том, что люди используют и то, и другое, не задумываясь об этом. Почему срок действия неизменяемых данных конфигурации должен истекать? Был один клиент, который кэшировал там данные и все еще создавал объекты ADO DB и т. Д., Когда в последний раз они проверяли, был ли он в кеше. По сути, оба эти решения будут работать для вас, но для получения положительного эффекта убедитесь, что вы используете кеш/синглтон. В любом случае, если ваши данные недоступны, оба должны быть обновлены в этот момент.

person RTZ ZZ    schedule 27.12.2018