Синглтон против кеша 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;
        }
    }
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
5 618
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

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

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

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

Да, когда AppDomain перезагружается, с новым экземпляром проблем не возникает. Но синглтон ведет себя как глобальный объект, не так ли? При тестировании я вижу, что ASP.NET не создает синглтон для каждого сеанса, а только синглтон для всего приложения.

Lieven Cardoen 19.11.2008 18:37

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

Это хорошая практика при использовании в правильном месте. К сожалению, я НИКОГДА не работал в месте, которое действительно является нужный, хотя я видел их реализованные сотни раз :) MonoState - хорошая альтернатива.

Ben Scheirman 19.11.2008 17:41

Чтобы ответить на ваш вопрос, у меня 200 кандидатов одновременно запрашивают один и тот же ExamDTO (по идентификатору). Я видел, что код на стороне сервера 200 раз заходил в базу данных для сдачи экзамена. Теперь я хотел кэшировать экзамен по его идентификатору, чтобы после загрузки сервер не переходил в базу данных снова.

Lieven Cardoen 19.11.2008 18:43

Тогда вам нужен кеш (ни одного сингла, перепутать их опасно). Для одного предложения см. Комментарий Бена к MonoState. В противном случае скройте кеширование в вашем слое данных. Хорошие картографы O / R, такие как NHibernate, уже поддерживают подобные вещи.

user35149 19.11.2008 19:18

Другой вопрос (извините за любопытство): это вызывает у вас проблемы с производительностью? Вы будете удивлены, но 200 запросов на одну и ту же запись - это легкий ветерок для большинства современных dbs. Если у вас возникла проблема с перфомансом, я полностью понимаю необходимость кеширования.

user35149 19.11.2008 19:24

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

Lieven Cardoen 19.11.2008 21:23

В чем разница между кешем и синглтоном? Поведение выглядит одинаково ... Синглтон можно вызывать из любого сеанса (это как глобальная переменная).

Lieven Cardoen 19.11.2008 21:24

Я посмотрел на MonoState, и разве Singleton не является чем-то вроде MonoState с одной статической переменной, самим экземпляром?

Lieven Cardoen 19.11.2008 21:27

Синглтон предназначен для ограничения класса только одним экземпляром с глобальным доступом. Шаблон моносостояния - это способ, которым несколько экземпляров имеют общее состояние. Кэш предоставляет доступ к одному и тому же объекту несколько раз без создания их новых экземпляров. MonoState - это ОДИН способ реализации кеша.

user35149 20.11.2008 12:58

«Синглтон может быть вызван из любого сеанса (это как глобальная переменная)» И глобальные переменные ПЛОХО и НЕ являются правильным использованием шаблона синглтона.

user35149 20.11.2008 13:02

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

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

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

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

Что это за дополнительные функции?

Lieven Cardoen 19.11.2008 22:45

Истечение срока действия / удаление элементов из памяти.

Greg 22.11.2008 01:59
Ответ принят как подходящий

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

частный статический экземпляр ExamDTORegistry ТОЛЬКО ДЛЯ ЧТЕНИЯ;

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

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

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