Замена сеанса ASP.Net полностью

Сессия ASP.Net выглядит идеально для традиционного приложения WebForms, но они делают некоторые вещи, которые являются серьезной проблемой для современного приложения AJAX и MVC.

В частности, есть только 3 способа доступа к поставщику ASP.Net:

  • Блокировка чтения и записи (по умолчанию) - сеанс заблокирован от AcquireRequestState срабатывания до ReleaseRequestState. Если из браузера сразу появятся 3 запроса, они будут стоять в очереди на сервере. Это единственный вариант в MVC 2, но MVC 3 позволяет...

  • Только для блокировки только для чтения - сеанс не заблокирован, но не может быть сохранен. Это выглядит как ненадежным, хотя, поскольку некоторые чтения, похоже, снова блокируют сеанс.

  • Сессия отключена - любая попытка чтения или записи на сеанс выдает исключение.

Однако с современным MVC-приложением у меня много событий AJAX, происходящих сразу - я не хочу, чтобы они были на очереди на сервере, но я хочу, чтобы они могли писать на сеанс.

Что я хочу - это четвертый режим: Грязное чтение, последние записи выигрывают

Я думаю (счастлив быть исправленным), что единственный способ сделать это - полностью заменить сеансы ASP.Net. Я могу написать собственный собственный поставщик, но ASP все равно вызовет его с одним из трех исправлений, которые он поддерживает. Есть ли способ сделать оптимизацию ASP.Net concurrency?

Это оставляет меня заменой всех вызовов на сеанс новым классом, который в основном делает то же самое, но не блокирует - это боль.

Я хочу сохранить как можно больше текущих файлов сеанса (в основном, идентификаторов сеансов в разных журналах) с минимальным количеством замены кода. Есть какой-либо способ сделать это? В идеале я бы хотел, чтобы HttpContext.Current.Session указывал на мой новый класс, но без ASP.Net блокировал любые запросы.

Кто-нибудь уже сделал что-то подобное? Кажется странным, что со всеми приложениями AJAXey MVC это новая проблема с ASP.

Ответ 1

Прежде всего, я говорю, что MS asp.net имеет блокировку в ядре "asp.net обработки страницы" сессии, где-то в dll " webengine4.dll" для asp.net 4

И я говорю это с точки зрения MS asp.net act correct and lock the session this way, потому что asp.net не может знать, какую информацию мы храним на сессии, поэтому можем сделать правильные "последние победы записи".

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

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

мы имеем древовидные переменные в сеансе, "VAR1", "VAR2", "VAR3"

Страница 1.
getession (фактически получить все данные и поместить их в список)
сеанс [VAR1] = "data1";
savesession()
результатом является VAR1 = data1, VAR2 = (последние данные var2), VAR3 = (последние данные var3)

Страница 2.
getession (фактически получить все данные и поместить их в список)
сеанс [VAR2] = "data2";
savesession()
результатом является VAR1 = (последние данные var1), VAR2 = data2, VAR3 = (последние данные var3)

Страница 3.
getession (фактически получить все данные и поместить их в список)
сеанс [VAR3] = "data3";
savesession()
результатом является VAR1 = (последние данные var1), VAR2 = (последние данные var2) VAR3 = "data3"

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

Если мы допустим, чтобы эти 3 страницы работали без блокировки, у нас нет действительно грязного чтения, более поздняя "последняя запись выигрывает" - то, что мы имеем здесь, ", последняя запись уничтожает остальные", потому что, если вы снова это почувствуете, когда VAR1 изменится, почему VAR2 и VAR3 остаются неизменными? что, если у вас есть изменение VAR2 где-то еще.

и по этой причине мы не можем позволить этому с блокировкой, как есть.

И теперь изображение, что с 20 переменными... полностью беспорядок.

Возможные решения

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

Я выбираю, чтобы общая база данных была проще, чем создавать программу для этого.

Теперь, если мы подключаем cookie, который мы делаем, пользователю к пользователю данных сеанса, и мы управляем данными, используя полностью настраиваемое поле базы данных, которое мы знаем, что нам нравится блокировать, что нет, как сохранить или изменить, или сравнить и сохранить последние записи, выигрывает данные, мы можем сделать эту работу и полностью отключить сессию asp.net, которая является универсальным хранителем сеанса, созданным для всех но не предназначен для обработки особых случаев, подобных этому.

Может ли asp.net выполнить эту работу над будущей версией, да, он может, добавив лишнее поле, называемое грязным, и в сеансе сохранить данные, сделать слияние данных с использованием грязного поля или что-то в этом роде, но может не делайте это сейчас так, как есть - по крайней мере, от того, что я нашел до сих пор.
 Фактически у SessionStateItem есть грязный флаг в свойствах, но он не сделал это слияние в конце сохранения данных. Мне очень понравится, если кто-то еще подумает о решении существующего хранителя сеанса ms asp.net, я пишу то, что я нашел до сих пор, но это не значит, что, конечно, нет способа - я не знаю, нашел это как есть.

Надеюсь, что все поможет:)

Пользовательский SessionStateModule

в этом ответе fooobar.com/info/21246/... Джеймс после написания пользовательского модуля говорит: Я все еще не могу поверить, что пользовательская реализация блокировок сеанса ASP.Net сеанс для всего запроса.