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

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

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

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

  2. Без блокировки только для чтения - сеанс не заблокирован, но не может быть сохранен. Однако это кажется ненадежным, так как некоторые операции чтения снова блокируют сеанс.

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

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

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

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

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

Я хочу сохранить как можно больше информации о текущем сеансе (наиболее существенно идентификаторы сеансов в различных журналах) с минимальным количеством замены кода. Есть какой-либо способ сделать это? В идеале я бы хотел 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.
getsession (фактически получить все данные и поместить их в список)
сеанс [VAR1] = "данные1";
savesession ()
результат VAR1=data1, VAR2=(последние данные var2), VAR3=(последние данные var3)

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

Страница 3.
getsession (фактически получить все данные и поместить их в список)
сеанс [VAR3] = "данные3";
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

В этом ответе /questions/47878998/ya-tolko-chto-vyiyasnil-pochemu-vse-sajtyi-aspnet-rabotayut-medlenno-i-ya-pyitayus-ponyat-chto-s-etim-delat/47879144#47879144 Джеймс после записи пользовательского модуля говорит: Я все еще не могу поверить, что пользовательская реализация ASP.Net Session блокирует сеанс для всего запроса.

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