Идеальный способ перенаправления - позвонить Response.Redirect(someUrl, false)
, а затем позвонить CompleteRequest()
Передача false в Response.Redirect(...)
предотвратит повышение ThreadAbortException
, однако по-прежнему важно завершить жизненный цикл страницы, вызвав CompleteRequest()
.
Когда вы используете этот метод в обработчике страницы для завершения запроса
одну страницу и начать новый запрос для другой страницы, установите endResponse в
false и затем вызывают метод CompleteRequest () . Если вы укажете истину
для параметра endResponse этот метод вызывает метод End для
исходный запрос, который генерирует исключение ThreadAbortException
когда это завершится. Это исключение имеет пагубное влияние на сеть
производительность приложения, поэтому передает false для
Параметр endResponse рекомендуется . Для получения дополнительной информации см.
Завершить метод.
Обратите внимание, что при вызове метода Response.Redirect(...)
создается новый поток с новым жизненным циклом страницы для обработки нового перенаправленного ответа. Когда новый ответ заканчивается, он вызывает Response.End()
в исходном ответе, который в конечном итоге выдает ThreadAbortException
и вызывает событие EndRequest
. Если вы препятствуете вызову Response.End()
(путем передачи false на Response.Redirect
), тогда вам нужно позвонить CompleteRequest()
, который:
Заставляет ASP.NET обходить все события и фильтрацию в конвейере HTTP.
цепочка выполнения и непосредственно выполнить событие EndRequest.
Слово предостережения:
Если вы позвоните по номеру Response.Redirect(someUrl, false)
, позволяющему продолжить выполнение кода, вы можете изменить свой код так, чтобы обработка корректно прекратилась. Иногда это так же просто, как добавить return
к вызову метода void. Однако, если вы находитесь в глубоком стеке вызовов, это намного сложнее, и если вы не хотите, чтобы больше кода выполнялось, было бы легче передать true, как Response.Redirect(someUrl, true)
, и преднамеренно ожидать ThreadAbortException
- что, кстати, не является ' Плохая вещь, вы должны ожидать этого во время Response.Redirect(...)
и Server.Transfer(...)
звонков.
ThreadAbortException не может быть остановлено путем перехвата исключения
ThreadAbortException не является вашим обычным исключением. Даже если вы поместите свой код в блок try catch, исключение ThreadAbortException сразу же будет вызвано после предложения finally.
Когда вызывается метод Abort для уничтожения потока,
общеязыковая среда выполнения выдает исключение ThreadAbortException.
ThreadAbortException - это особое исключение, которое может быть перехвачено, но оно
автоматически поднимется снова в конце блока захвата . когда
это исключение возникает, среда выполнения выполняет все блоки finally
до окончания потока. Потому что поток может делать неограниченное
вычисление в блоках finally или вызов Thread.ResetAbort для отмены
прерывание , нет никакой гарантии, что поток когда-либо закончится. если ты
хотите дождаться окончания прерванного потока, вы можете вызвать
Thread.Join метод. Присоединение - это блокирующий вызов, который не возвращается до
поток фактически останавливается.
Часто в коде я видел блок try catch для Response.Redirect, который будет регистрировать исключения, которые не являются ThreadAbortExceptions (так как вы ожидаете их). Пример: * 1 059 *
private void SomeMethod()
{
try
{
// Do some logic stuff
...
if (someCondition)
{
Response.Redirect("ThatOneUrl.aspx", true);
}
}
catch (ThreadAbortException)
{
// Do nothing.
// No need to log exception when we expect ThreadAbortException
}
catch (Exception ex)
{
// Looks like something blew up, so we want to record it.
someLogger.Log(ex);
}
}