КОД:
Session["foo"] = "bar";
Response.Redirect("foo.aspx");
ПРОБЛЕМА:
Когда foo.aspx читает "нечто" из сессии, это не там. Сессия там, но нет никакого значения для "нечто".
Я наблюдал это периодически в нашей продуктивной среде. Но я не означаю здесь задавать вопрос об Ответе. Перенаправление ().
ОБЪЯСНЕНИЕ:
Bertrand Ле-Рой объясняет (выделение полужирным является моим):
Теперь, то, что делает Перенаправление, должно отправить специальный заголовок клиенту так, чтобы оно попросило у сервера другой страницы, чем та, которой оно ожидало. Серверная сторона, после отправки этого заголовка, Перенаправление заканчивает ответ. Это - очень сильная вещь сделать. Ответ. Конец на самом деле останавливает выполнение страницы везде, где это использует ThreadAbortException. Что происходит действительно, вот то, что маркер сессии теряется в сражении.
Моей едой на дом там является тот Ответ. Перенаправление () может быть властным с окончанием потоков. И это может угрожать моим записям сессии, если они происходят также около той властности.
ВОПРОС:
Что относительно ASP.NET управление сеансами делает его настолько уязвимым для этого? Ответ. Перенаправление () строка кода не начинает свое выполнение, пока строка записи сессии не "закончена" - как это может быть такая угроза моей записи сессии?
Что относительно сессии не "заканчивается" запись, прежде чем следующая строка кода выполняется? Есть ли другие сценарии, в которых записи сессии так же (как будто они никогда не происходили), потерянный?
Я недостаточно знаком с внутренним устройством записи сеанса, но я полагаю, что у него есть некоторые сложности, поскольку он основан на переводе файлов cookie сеанса браузера в идентификация сервера. Кроме того, ThreadAbortExceptions имеет особые соображения во время выполнения, которые могут сыграть здесь роль, я не уверен.
В любом случае, Response.Redirect ()
имеет перегрузку, которая принимает логический параметр, который позволяет вам указать, хотите ли вы завершить поток или нет.
Response.Redirect(string url, bool endResponse);
Если вы вызываете его с параметром endResponse, установленным в «false», он будет корректно завершен, вместо внутреннего вызова Thread.Abort ()
. Однако это означает, что он также выполнит любой код, оставшийся в жизненном цикле страницы, до завершения.
Хорошим компромиссом является вызов Response.Redirect (url, false)
, за которым следует Application.CompleteRequest ()
. Это позволит выполнить перенаправление, но также корректно завершит текущий контекст выполнения с минимальным объемом дополнительной обработки жизненного цикла.
Переработка пула приложений может привести к тому, что ваша сессия исчезнет. Вы можете настроить пул приложений на переработку в фиксированное время (рекомендуется, а также ночью или в периоды низкого использования) или увеличить период таймаута переработки пула приложений.