Поведение Singleton с многопользовательскими запросами в ASP.NET - PullRequest
0 голосов
/ 07 января 2011

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

Вот сценарий:

В событии AppStart я хочу загрузить общие данные для всех пользователей (из SQL) и сохранить их как коллекцию где-нибудь в механизмах хранения ASP.NET. (Любые указатели относительно того, куда это должно пойти, были бы очень благодарны! Я думаю, кэш.)

Если я сохраню эти данные в кеше, мне также потребуется создать статическое свойство в Global.asax, которое обеспечит доступ к этим данным из кеша.

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

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

В событии PostAuthenticate я хочу получить пользовательские данные из SQL в виде коллекции. Если я храню его как единое целое (аналогично обычным данным), мне не ясно, как:

  1. Как сохраняются данные?
  2. Какова область действия этого синглтона (оно должно быть на протяжении сеанса пользователя).
  3. Как я могу обеспечить немедленную доступность данных для любых нужд, которые их потребляют?
  4. Что происходит между постбеками этого синглтона?
  5. Если другой пользователь войдет в систему, будет ли создан другой экземпляр этого синглтона для этого конкретного экземпляра приложения?

1 Ответ

1 голос
/ 07 января 2011

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

Кэш времени выполнения является хранилищем оперативной памяти, поэтому накладные расходы на доступ к объектам низкие.

В качестве альтернативы, вы можете хранить данные в общем статическом свойстве ("singleton"), и оно будет доступно всем пользователям (в рамках рабочего процесса).

Вы не хотите хранить данные, относящиеся к конкретному пользователю / сеансу, как одноэлементные, поскольку статические экземпляры являются общими для всех запросов. Одним из вариантов является использование состояния сеанса для хранения пользовательских данных. По умолчанию состояние сеанса также обрабатывается ...

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

Другой вариант - снова использовать кэш времени выполнения, но использовать составной ключ, такой как «UserData |» + UserId для хранения и извлечения данных для каждого пользователя. Это позволяет вам устанавливать ограничения по времени для кэшируемого элемента, и кэш будет очищать старые / низкоприоритетные элементы, если память становится слишком низкой.

...