这篇知识库文章说,ASP.NET Response.End()中止了一个帖子.
反射器显示它看起来像这样:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎很苛刻.正如知识库文章所说,以下应用程序中的任何代码Response.End()都不会被执行,这违反了最不惊讶的原则.它几乎就像Application.Exit()在WinForms应用程序中.造成线程终止异常Response.End()不开捕,所以代码周围的try...... finally不会满足.
这让我想知道我是否应该总是避免Response.End().
任何人都可以建议,我什么时候应该使用Response.End(),何时Response.Close()何地HttpContext.Current.ApplicationInstance.CompleteRequest()?
参考:Rick Strahl的博客文章.
根据我收到的输入,我的回答是,是的,Response.End是有害的,但在某些有限的情况下它是有用的.
Response.End()作为一个不可捕获抛出,立即终止HttpResponse在特殊的条件.在调试过程中也很有用. 避免Response.End()完成常规反应.Response.Close()立即关闭与客户端的连接.根据此MSDN博客文章,此方法不适用于正常的HTTP请求处理. 你不太可能有充分的理由来调用这种方法.CompleteRequest()结束正常请求. 在当前事件完成后CompleteRequest,ASP.NET管道将跳转到事件.因此,如果您打电话,然后在响应中写入更多内容,则会将写入内容发送给客户端.EndRequestHttpApplicationCompleteRequest编辑 - 2011年4月13日
可在此处进一步了解:
- MSDN博客上的有用帖子
- Jon Reid的有用分析
use*_*430 106
最初我建议您只需用[...] CompleteRequest()调用替换所有对[Response.End]的调用,但是如果你想避免回发处理和html渲染,你需要添加[.. .]也覆盖.
Jon Reid,"最终分析"
Server.Transfer,Response.Redirect,Response.End方法都引发异常.这些方法中的每一个都在内部调用Response.End.反过来,对Response.End的调用会导致ThreadAbortException异常.
HttpApplication.CompleteRequest()设置一个变量,该变量使线程跳过HttpApplication事件管道[ - ]中的大多数事件而不是Page事件链而不是Application事件链.
...
创建一个类级别变量,标记页面是否应终止,然后在处理事件或呈现页面之前检查变量.[...]我建议只重写RaisePostBackEvent和Render方法
当性能很重要时,Response.End和Response.Close不用于正常的请求处理.Response.End是一种方便,严厉的终止请求处理的方法,具有相关的性能损失.Response.Close用于在IIS /套接字级别立即终止HTTP响应,并导致KeepAlive等问题.
结束ASP.NET请求的推荐方法是HttpApplication.CompleteRequest.请记住,必须手动跳过ASP.NET呈现,因为HttpApplication.CompleteRequest会跳过IIS/ASP.NET应用程序管道的其余部分,而不是ASP.NET页面管道(这是应用程序管道中的一个阶段).
版权所有©2001-2007,C6 Software,Inc尽我所知.
导致ASP.NET绕过所有事件并在HTTP管道执行链中进行过滤,并直接执行EndRequest事件.
此方法仅用于与ASP兼容,即与ASP.NET.preceded ASP.NET之前的基于COM的Web编程技术兼容.[强调补充]
此方法以突然方式终止与客户端的连接, 并非用于正常的HTTP请求处理.[强调补充]
Jay*_*los 96
这个问题出现在所有谷歌搜索的顶部附近有关response.end的信息,所以对于像我这样的其他搜索,如果他们希望发布CSV/XML/PDF等以响应事件而不渲染整个ASPX页面,这就是我的工作方式.(对于这样一个简单的任务IMO,覆盖渲染方法过于复杂)
// Add headers for a csv file or whatever
Response.ContentType = "text/csv"
Response.AddHeader("Content-Disposition", "attachment;filename=report.csv")
Response.AddHeader("Pragma", "no-cache")
Response.AddHeader("Cache-Control", "no-cache")
// Write the data as binary from a unicode string
Dim buffer As Byte()
buffer = System.Text.Encoding.Unicode.GetBytes(csv)
Response.BinaryWrite(buffer)
// Sends the response buffer
Response.Flush()
// Prevents any other content from being sent to the browser
Response.SuppressContent = True
// Directs the thread to finish, bypassing additional processing
HttpContext.Current.ApplicationInstance.CompleteRequest()
Run Code Online (Sandbox Code Playgroud)
spo*_*son 64
如果您在应用程序上使用了异常记录器,则会使用ThreadAbortException这些良性Response.End()呼叫中的s 来淡化它.我认为这是微软的说法"敲掉它!".
我只会使用,Response.End()如果有一些特殊情况,没有其他行动是可能的.也许那时,记录此异常可能实际上表示警告.
Jan*_*ola 11
关于"我仍然不知道Response.Close和CompleteRequest()之间的区别"我会说:
更喜欢CompleteRequest(),不要使用Response.Close().
有关此案例的完善摘要,请参阅以下文章.
请注意,即使在调用CompleteRequest()之后,某些文本(例如,从ASPX代码重新编译)也会附加到响应输出流中.您可以通过重写Render和RaisePostBackEvent方法来阻止它,如下文所述.
BTW:我同意阻止使用Response.End(),特别是在将数据写入http流以模拟文件下载时.我们过去曾使用过Response.End(),直到我们的日志文件充满了ThreadAbortExceptions.
我不同意声明" Response.End是有害的 ".这绝对没有害处.Response.End做它说的话; 它结束了页面的执行.使用反射器来查看它的实现方式只应被视为具有指导意义.
我的2cent建议使用作为控制流程
避免Response.End().
不要使用Response.End(),如果你需要停止执行的请求,并注意(典型值)*无码将执行过去的那个点.
*Response.End()和ThreadAbortException.
Response.End() 抛出ThreadAbortException作为其当前实现的一部分(如OP所述).
ThreadAbortException是一个可以捕获的特殊异常,但它会在catch块的末尾自动再次引发.
要了解如何编写必须处理ThreadAbortExceptions的代码,请参阅@ Mehrdad对SO的回复如何在finally块中检测一个threadabortexception,其中他引用了RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup方法和约束执行区域
提到的Rick Strahl文章很有启发性,请务必阅读评论.请注意,Strahl的问题是具体的.他希望将数据提供给客户端(图像),然后处理命中跟踪数据库更新,这不会减慢图像的服务速度,这使他在调用Response.End后做了一些事情.
| 归档时间: |
|
| 查看次数: |
76587 次 |
| 最近记录: |