Может ли один пользователь asp.net выполнять несколько запросов одновременно, если сеанс используется?

Я не могу делать несколько запросов одновременно в asp.net во время сеанса. Почему это ограничение существует? Есть ли способ обойти это?

Эта проблема может быть продемонстрирована с помощью приложения WebForms с тремя простыми страницами aspx (хотя ограничение все еще применяется в asp.net mvc).

Создайте веб-приложение asp.net 3.5.

Должно быть только три страницы: NoWait.aspx, Wait.aspx и SessionStart.aspx

NoWait.aspx имеет этот единственный самородок, добавленный между тегами div по умолчанию: <% = DateTime.Now.Ticks% > . Код для этой страницы по умолчанию (пустой).

Wait.aspx выглядит так же, как и NoWait.aspx, но имеет одну строку, добавленную к странице_Load в коде: Thread.Sleep(3000);//ждать 3 секунды

SessionStart.aspx также выглядит так же, как NoWait.aspx, но у него есть эта единственная строка в коде: Session [ "Whatever" ] = "Anything";

Откройте браузер и перейдите в NoWait.aspx. Он правильно отображает число в ответе, например: "633937963004391610". Продолжайте обновлять, и он продолжает изменять номер. Отлично! Создайте новую вкладку в том же браузере и перейдите в Wait.aspx. Он сидит в течение 3 секунд, затем записывает номер в ответ. Отлично! Нет, попробуйте это: перейдите в Wait.aspx и, пока он вращается, быстро перейдите на NoWait.aspx и обновите. Даже когда Wait.aspx спал, NoWait.aspx WILL дает ответ. Отлично. Вы можете продолжить обновление NoWait.aspx, пока Wait.aspx вращается, и сервер с радостью отправляет ответ каждый раз. Это поведение, которое я ожидаю.

Теперь это странно.

На третьей вкладке в том же браузере зайдите на SessionStart.aspx. Затем перейдите в Wait.aspx и обновите. Пока он вращается, перейдите на NoWait.aspx и обновите. NoWait.aspx НЕ отправит ответ, пока Wait.aspx не будет запущен!

Это доказывает, что пока сеанс активен, вы не можете делать одновременные запросы с одним и тем же пользователем. Запросы помещаются в очередь и обслуживаются синхронно. Я не ожидаю и не понимаю этого поведения. Я тестировал это на Visual Studio 2008, построенном на веб-сервере, а также IIS 7 и IIS 7.5.

Итак, у меня есть несколько вопросов:

1) Я исправлю, что здесь действительно существует ограничение, или мой тест выше недействителен, потому что я делаю что-то неправильно?

2) Есть ли способ обойти это ограничение? В моем веб-приложении некоторые вещи занимают много времени, и я хотел бы, чтобы пользователи могли делать что-то на других вкладках, пока они ждут завершения большого запроса. Могу ли я каким-то образом настроить сеанс, чтобы разрешить "грязные чтения"? Это может помешать блокировке во время запроса?

3) Почему это ограничение существует? Я хотел бы получить хорошее представление о том, почему это ограничение необходимо. Думаю, я был бы лучшим разработчиком, если бы знал!

Ответы

Ответ 1

Вот ссылка, говорящая о состоянии сеанса и блокировке. Он выполняет и исключительную блокировку.

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

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

Это не слишком удивительно, что это может быть ограничение. Каждый браузер имел бы свою собственную сессию, до появления ajax, запросы обратной связи были синхронными. Одновременная обработка дескриптора сеанса может стать действительно уродливой, и я вижу, как это не будет приоритетом для команд IIS и ASP.NET.

Ответ 2

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

Чтобы обойти это, страницы, которые только считывают данные сеанса, могут объявить, что они это делают. ASP.NET не получит для них блокировку записи состояния сеанса:

// Or false if it doesn't need access to session state at all
EnableSessionState="ReadOnly"