Cet article de la base de Response.End()
connaissances indique que ASP.NET abandonne un thread.
Le réflecteur montre que cela ressemble à ceci:
public void End()
{
if (this._context.IsInCancellablePeriod)
{
InternalSecurityPermissions.ControlThread.Assert();
Thread.CurrentThread.Abort(new HttpApplication.CancelModuleException(false));
}
else if (!this._flushing)
{
this.Flush();
this._ended = true;
if (this._context.ApplicationInstance != null)
{
this._context.ApplicationInstance.CompleteRequest();
}
}
}
Cela me semble assez dur. Comme le dit l'article de la base de connaissances, aucun code de l'application suivante Response.End()
ne sera exécuté, ce qui viole le principe du moindre étonnement. C'est presque comme Application.Exit()
dans une application WinForms. L'exception d'annulation de thread provoquée par Response.End()
n'est pas capturable, donc entourer le code dans un try
... finally
ne sera pas satisfaisant.
Je me demande si je devrais toujours éviter Response.End()
.
Quelqu'un peut-il suggérer, quand dois-je utiliser Response.End()
, quand Response.Close()
et quand HttpContext.Current.ApplicationInstance.CompleteRequest()
?
réf: entrée de blog de Rick Strahl .
Sur la base des informations que j'ai reçues, ma réponse est oui, Response.End
est nuisible , mais elle est utile dans certains cas limités.
- utiliser
Response.End()
comme un jet inaccessible, pour terminer immédiatement leHttpResponse
dans des conditions exceptionnelles. Peut également être utile lors du débogage. ÉvitezResponse.End()
de compléter les réponses de routine . - utiliser
Response.Close()
pour fermer immédiatement la connexion avec le client. Selon cet article de blog MSDN , cette méthode n'est pas destinée au traitement normal des requêtes HTTP. Il est très peu probable que vous ayez une bonne raison d'appeler cette méthode. - utiliser
CompleteRequest()
pour mettre fin à une demande normale.CompleteRequest
entraîne le pipeline ASP.NET à passer à l'EndRequest
événement, une fois l'HttpApplication
événement en cours terminé. Donc, si vous appelezCompleteRequest
, puis écrivez quelque chose de plus dans la réponse, l'écriture sera envoyée au client.
Edit - 13 avril 2011
Plus de clarté est disponible ici:
- Article utile sur le blog MSDN
- Analyse utile par Jon Reid
Response.End
ThreadAbortException
très bien.Response.Redirect
et à laServer.Transfer
fois appelResponse.End
et devrait également être évité.Réponses:
Si vous aviez utilisé un enregistreur d'exceptions sur votre application, il sera édulcoré avec les
ThreadAbortException
s de cesResponse.End()
appels bénins . Je pense que c'est la manière de Microsoft de dire "Arrête!".Je n'utiliserais que
Response.End()
s'il y avait une condition exceptionnelle et qu'aucune autre action n'était possible. Peut-être qu'alors, l'enregistrement de cette exception pourrait en fait indiquer un avertissement.la source
TL; DR
Selon MSDN, Jon Reid et Alain Renon:
Performances ASP.NET - Gestion des exceptions - Écrire du code qui évite les exceptions
Solution ThreadAbortException
Response.End et Response.Close ne sont pas utilisés dans le traitement normal des demandes lorsque les performances sont importantes. Response.End est un moyen pratique et compliqué de terminer le traitement des demandes avec une pénalité de performance associée. Response.Close est pour l'arrêt immédiat de la réponse HTTP au niveau IIS / socket et provoque des problèmes avec des choses comme KeepAlive.
La méthode recommandée pour mettre fin à une demande ASP.NET est HttpApplication.CompleteRequest. Gardez à l'esprit que le rendu ASP.NET devra être ignoré manuellement car HttpApplication.CompleteRequest ignore le reste du pipeline d'application IIS / ASP.NET, pas le pipeline de page ASP.NET (qui est une étape du pipeline d'application).
Code
Copyright © 2001-2007, C6 Software, Inc du mieux que je puisse dire.
Référence
HttpApplication.CompleteRequest
Response.End
Réponse.Fermer
la source
Cette question apparaît en haut de toutes les recherches Google pour obtenir des informations sur response.end donc pour d'autres recherches comme moi qui souhaitent publier CSV / XML / PDF, etc. en réponse à un événement sans afficher l'intégralité de la page ASPX, voici comment je le fais . (remplacer les méthodes de rendu est trop complexe pour une tâche aussi simple IMO)
la source
Sur la question "Je ne connais toujours pas la différence entre Response.Close et CompleteRequest ()", je dirais:
Préférez CompleteRequest (), n'utilisez pas Response.Close ().
Voir l' article suivant pour un résumé bien fait de ce cas.
N'oubliez pas que même après avoir appelé CompleteRequest (), du texte (par exemple redndered à partir du code ASPX) serait ajouté au flux de sortie de la réponse. Vous pouvez l'empêcher en remplaçant les méthodes Render et RaisePostBackEvent comme décrit dans l' article suivant .
BTW: Je suis d'accord pour empêcher l'utilisation de Response.End (), en particulier lors de l'écriture de données dans le flux http pour émuler le téléchargement de fichiers. Nous avons utilisé Response.End () dans le passé jusqu'à ce que notre fichier journal soit rempli de ThreadAbortExceptions.
la source
Je ne suis pas d'accord avec l'énoncé " Response.End is nocive ". Ce n'est certainement pas nocif. Response.End fait ce qu'il dit; il termine l'exécution de la page. Utiliser le réflecteur pour voir comment il a été mis en œuvre ne doit être considéré que comme instructif.
Ma 2cent Recommandation
ÉVITER en utilisant
Response.End()
comme flux de contrôle.À utiliser
Response.End()
si vous devez arrêter l'exécution de la demande et sachez que (généralement) * aucun code ne sera exécuté après ce point.*
Response.End()
et ThreadAbortException s.Response.End()
lève une exception ThreadAbortException dans le cadre de son implémentation actuelle (comme indiqué par OP).Pour voir comment écrire du code qui doit gérer les ThreadAbortExceptions, voir la réponse de @ Mehrdad à SO Comment puis-je détecter une threadabortexception dans un bloc finally où il fait référence à RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup et aux régions d'exécution contraintes
L' article de Rick Strahl mentionné est instructif et assurez-vous de lire également les commentaires. Notez que le problème de Strahl était spécifique. Il voulait transmettre les données au client (une image), puis traiter la mise à jour de la base de données de suivi des hits qui ne ralentissait pas la diffusion de l'image, ce qui lui posait le problème de faire quelque chose après que Response.End ait été appelé.
la source
Je n'ai jamais envisagé d'utiliser Response.End () pour contrôler le flux du programme.
Cependant Response.End () peut être utile par exemple lors du service de fichiers à un utilisateur.
Vous avez écrit le fichier dans la réponse et vous ne voulez rien ajouter à la réponse car cela pourrait corrompre votre fichier.
la source
J'ai utilisé Response.End () dans .NET et ASP classique pour terminer les choses avec force auparavant. Par exemple, je l'utilise lorsqu'il y a un nombre certian de tentatives de connexion. Ou lorsqu'une page sécurisée est accédée à partir d'une connexion non authentifiée (exemple grossier):
Lors de la diffusion de fichiers à un utilisateur que j'utiliserais un vidage, la fin peut provoquer des problèmes.
la source
Je n'ai utilisé que Response.End () comme mécanisme de test / débogage
À en juger par ce que vous avez publié en termes de recherche, je dirais que ce serait une mauvaise conception si elle nécessitait une réponse.
la source
Sur asp classique, j'avais un TTFB (Time To First Byte) de 3 à 10 secondes sur certains appels ajax, beaucoup plus grand que le TTFB sur les pages régulières avec beaucoup plus d'appels SQL.
L'ajax retourné était un segment de HTML à injecter dans la page.
Le TTFB était plusieurs secondes plus long que le temps de rendu.
Si j'ai ajouté un response.end après le rendu, le TTFB a été considérablement réduit.
Je pourrais obtenir le même effet en émettant un "</body> </html>", mais cela ne fonctionne probablement pas lors de la sortie de json ou xml; ici response.end est nécessaire.
la source