2013-04-27 1 views
4

Мне было интересно, нужно ли оставить заявление return после моего звонка Response.RedirectPermanent в моем коде? Это не похоже на это, но я хотел подтвердить с другими.В ASP codebehind есть ли какая-либо польза от добавления ключевого слова return после перенаправления?

Response.RedirectPermanent(vpd.VirtualPath); 
return; 

Есть ли основания для этого либо для увеличения функциональности, либо усиления производительности?

+0

Является ли 'return;' последним в вашем методе или у вас есть другой код после него, который он пропускал бы? –

ответ

4

Ответственный ремонт:

Удерживайте телефон! Детали в моем предыдущем ответе были, следуя дальнейшим исследованиям, совсем не верны. На самом деле, в документации MSDN определяет следующее:

При использовании этого метода в обработчике страницы для завершения запроса на одной странице и начать новый запрос на другую страницу, установите endResponse к ложным, а затем вызвать CompleteRequest метод. Если вы укажете true для параметра endResponse, этот метод вызывает метод End для исходного запроса, который генерирует исключение ThreadAbortException при его завершении. Это исключение оказывает пагубное влияние на производительность веб-приложения, поэтому рекомендуется передавать false для параметра endResponse.

http://msdn.microsoft.com/en-GB/library/a8wa7sdt.aspx

Таким образом, на самом деле, остальная часть страницы не выполняется (в теории - см «Update» ниже для примера, когда это падает); тем не менее, остается очень осязаемая проблема с тем, как вы это делаете, а именно, что механизм endResponse реализован путем выброса ThreadAbortException, что является относительно дорогостоящим способом прекращения обработки текущего потока.

Вместо этого, вы должны сказать ему, чтобы нить продолжать, но немедленно вернуться - и быть уверенным, что другие методы в стеке вызовов делают то, что они должны:

Response.RedirectPermanent(vpd.VirtualPath, false); 
return; 

еще лучше, обернуть вызов в условный, чтобы гарантировать, что нежелательный код не дозвонился, а затем использовать CompleteRequest метод (который не прекращается в настоящий момент выполняющегося кода, но будет обходить все последующие события):

if (_redirecting) 
{ 
    Response.RedirectPermanent(vpd.VirtualPath, false); 
    Context.ApplicationInstance.CompleteRequest(); 
} 
else 
{ 
    /* Code I don't want to execute if I do a redirect */ 
    DeleteUsersDataForever(_currentUser); 
} 

Там есть углубленная статья о это тема here, и даже сама документация имеет unhealthy distaste for the HttpResponse.End method, что называется так, если вы разрешаете Response.Redirect выполнять завершение ответа для вас.

Update: Кроме того, учитывая, что поток прекращается путем повышения исключения, что произойдет, если вы попытаетесь сделать ваш редирект внутри TRY/улова:

try 
{ 
    // Redirect and terminate execution 
    Response.Redirect(someUrl, true); 
} 
catch 
{ 
    // Handle some errors. 
} 

DeleteUsersDataForever(_currentUser); 

Исключения, это поднятый Response.Endпойман в вашем блоке catch. Остальная часть вашего кода, тем не менее, выполняется, и вы случайно удалили все данные _currentUser (если вы не сделаете что-то, чтобы предотвратить это в вашем блоке catch, например, перекрывая исключение вызывающему).

+0

Примечание: Удаление данных пользователя навсегда при перенаправлении является _feature_, а не ошибкой! >.> –

2

Я попытался код ниже:

Page1.aspx

protected void Page_Load(object sender, EventArgs e) 
{ 
    Response.RedirectPermanent("~/Page2.aspx"); 
    Session["afterRedirect"] = "after redirect"; 
} 

Page2.aspx

protected void Page_Load(object sender, EventArgs e) 
{  
    Response.Write(Session["afterRedirect"] ?? "nothing to show"); 
} 

Результат

nothing to show

Код после RedirectPermanent не выполняется, так что Iguess с возвратом или нет будет иметь тот же эффект.

+0

Действительно, Response.Redirect пытается остановить выполнение страницы; однако это не всегда так просто, как ваш пример. Взгляните на мой ответ. –

Смежные вопросы