Может ли один пользователь asp.net сделать более одного запроса за раз, если сеанс используется? - PullRequest
15 голосов
/ 14 ноября 2009

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

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

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

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

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

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

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

Откройте браузер и перейдите на NoWait.aspx. Он правильно показывает число в ответе, например: «633937963004391610». Продолжайте освежаться, и он продолжает менять номер. Отлично, пока! Создайте новую вкладку в том же браузере и перейдите в Wait.aspx. Он сидит 3 секунды, затем записывает номер в ответ. Отлично, пока! Нет, попробуйте это: перейдите в Wait.aspx и, пока он вращается, быстро перейдите на NoWait.aspx и обновите. Даже когда Wait.aspx спит, NoWait.aspx предоставит ответ. Отлично, пока. Вы можете продолжать обновлять 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) Почему существует это ограничение? Я хотел бы получить хорошее понимание того, почему это ограничение необходимо. Я думаю, я был бы лучшим разработчиком, если бы знал!

Ответы [ 2 ]

11 голосов
/ 14 ноября 2009

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

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

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

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

9 голосов
/ 14 ноября 2009

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

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

// Or false if it doesn't need access to session state at all
EnableSessionState="ReadOnly"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...