Вы упоминаете (в своих комментариях к другому сообщению), что ваша проблема проявляется при вызове Response.Redirect (), потому что она вызывает исключение ThreadAbortException, которое приводит к тому, что ваше событие OnPreRender () не вызывается. Так почему бы не использовать это вместо этого?:
Response.Redirect("~/SomePage.aspx", false);
«Ложь», которую вы видите там, указывает, должно ли выполнение страницы немедленно прекратиться. По умолчанию Response.Redirect () использует «true». Если вам нужно, чтобы ваше событие OnPreRender () выполнялось так, чтобы у вашего события OnLoad () было все, что ему нужно, установите для него значение «false» и просто убедитесь, что вы либо перепрыгнули в конец вашей Page_Load () после вызова Response.Redirect. () или код, который будет выполняться после того, как он будет нормально работать.
Возможно, вам не нравится идея передать "false" с использованием перегруженного метода Response.Redirect (), поэтому вы не пошли по этому пути. Вот некоторые документы, которые могут повлиять на ваш разум:
Microsoft заявляет, что «, передавая false для параметра endResponse, рекомендуется », поскольку при указании «true» вызывается HttpResponse. Метод End () для исходного запроса, который затем выбрасывает ThreadAbortException, когда это завершается. Microsoft продолжает говорить, что « это исключение отрицательно влияет на производительность веб-приложений ». Смотрите в разделе «Замечания»: http://msdn.microsoft.com/en-us/library/a8wa7sdt.aspx
Это было опубликовано в прошлом году на MSDN :
Метод «Конец» также включен в мои «никогда
использовать »список. Лучший способ остановить
просьба позвонить
HttpApplication.CompleteRequest.
Конечный метод только там, потому что мы
пытался быть совместимым с классическим
ASP, когда 1.0 был выпущен. классический
ASP имеет метод Response.End, который
прекращает обработку ASP
скрипт. Чтобы подражать этому поведению,
Метод End в ASP.NET пытается поднять
ThreadAbortException. Если это
успешно, вызывающий поток будет
прервано (очень дорого, не подходит для
производительность) и конвейер будет
перейти к событию EndRequest.
ThreadAbortException, если
успешное, конечно, означает, что
поток раскручивается прежде, чем он сможет вызвать
больше кода, поэтому вызов End означает, что вы
после этого не буду звонить ни на какой код.
Если метод End не может поднять
ThreadAbortException, это будет
вместо этого сбросьте ответные байты
клиент, но это делает это
синхронно, что очень плохо для
производительность и когда пользовательский код
после завершения End,
конвейер прыгает вперед к EndRequest
уведомление. Запись байтов в
клиент очень дорогая операция,
особенно если клиент на полпути
по всему миру и используя 56k
модем, поэтому лучше отправлять байты
асинхронно, что мы и делаем
когда запрос заканчивается обычным способом.
Промывка синхронно действительно плохо.
Подводя итог, вы не должны использовать
Конец, но использование CompleteRequest
прекрасно. Документация для
Конец должен заявить, что CompleteRequest
это лучший способ перейти к
Уведомление EndRequest и завершено
запрос.
Я добавил эту строку после вызова Response.Redirect (), как предлагает MSDN, и заметил, что все работает одинаково. Не уверен, что это нужно с 4.0, но я не думаю, что это больно:
HttpContext.Current.ApplicationInstance.CompleteRequest();
Обновление 1
Using "false" в вызове Response.Redirect () избегает исключения ThreadAbortException, но как насчет других необработанных исключений, которые могут быть сгенерированы на вашей странице?Эти исключения по-прежнему будут вызывать проблему вызова OnUnload () без OnPreRender ().Вы можете использовать флаг в OnPreRender (), поскольку все предлагают избежать этого, но если вы выбрасываете необработанные исключения, у вас возникают большие проблемы, и в любом случае вам следует перенаправить на страницу с ошибкой.Поскольку необработанные исключения - это не то, что вы планируете выдавать при каждой обратной передаче, было бы лучше, если бы вы включили логику OnUnload () в Try-Catch.Если вы регистрируете и отслеживаете свои исключения, вы увидите, что необработанное исключение было сгенерировано прямо перед регистрацией исключения NullReference в событии OnUnload (), и узнаете, какое из них следует игнорировать.Поскольку у вашего OnUnload () будет Try-Catch, он безопасно продолжит обработку остальной части страницы, поэтому вы можете перенаправить на страницу ошибки, как и ожидалось.
Обновление 2
Вы все равно должнывключите OnUnload () в Try-Catch, но я думаю, что это то, что вы действительно ищете (помните, что IsRequestBeingRedirected будет истинным при вызове Response.Redirect или при перенаправлении на страницу ошибки после необработанного исключения).:
if (HttpContext.Current.Response.IsRequestBeingRedirected != true)
{
//You're custom OnUnload() logic here.
}
С этим вы узнаете, безопасно ли (или даже стоит ли) обрабатывать вашу пользовательскую логику в событии OnUnload ().Я понимаю, что, наверное, следовало покончить с этим, но я думаю, что сегодня мы многому научились.;)
ПРИМЕЧАНИЕ. Использование Server.Transfer () также вызовет страшный Response.End ().Чтобы избежать этого, вместо этого используйте Server.Execute () с атрибутом preserveForm , установленным в значение «false»:
Server.Execute("~/SomePage.aspx", false);
return;
ПРИМЕЧАНИЕ. Особенность Server.Execute ("~ / SomePage.aspx ", false);является то, что IsRequestBeingRedirected будет ложным, но ваш OnPreRender () все равно будет выполняться, поэтому не стоит беспокоиться.