我被告知Respond.Redirect是一个昂贵的过程,因为它引发了ThreadAbortException.所以相反,我们应该使用CompleteRequest函数.所以我试一试,但我注意到它下面的代码仍在运行,我不想要.我想立即强制浏览器跳转到另一个网站.
Public Shared Sub TestCompleteRequest()
If 1 = 1 Then
System.Web.HttpContext.Current.Response.Redirect("Http://Google.com", False)
System.Web.HttpContext.Current.ApplicationInstance.CompleteRequest()
End If
Throw New ApplicationException("Hello, why are you here?")
End Sub
Run Code Online (Sandbox Code Playgroud)
至于上面的代码,仍然抛出ApplicationException.但为什么?:(
最近我们遇到了一个问题,其中一个开发人员将代码行从使用HttpResponse.End改为使用HttpApplication.CompleteRequest时强制PDF以类似于以下方式下载:https:
//stackoverflow.com/a/8590579/3856039
这样做会导致某些PDF由于不间断的空间问题而无法下载,因此代码已更改回使用状态HttpResponse.End.
然而,在帮助我的同事进行一些研究时,我遇到了以下问题: Response.End()被认为是有害的吗?
链接到:https: //blogs.msdn.microsoft.com/aspnetue/2010/05/25/response-end-response-close-and-how-customer-feedback-helps-us-improve-msdn-documentation/
鉴于MSDN博客文章中记录的内容,听起来好像使用HttpResponse.End是错误的方法,所以我想知道它是否甚至需要或是否有更好的方法?
我在finally块中有一些关键逻辑(带有空的try块),因为我想保证即使线程被中止也会执行代码.但是,我还想检测ThreadAbortException.我发现在try/catch中包装我的关键try/finally块不会捕获ThreadAbortException.有没有办法检测它?
try {
try { }
finally {
// critical logic
}
} catch(Exception ex) {
// ThreadAbortException is not caught here, but exceptions thrown
// from within the critical logic are
}
有没有办法告诉IIS/ASP.NET不允许某些请求保持活动?或者甚至对整个网站来说,如果这真的是唯一的方法吗?
我处理一个请求begin_request.目前我使用Response.End()来阻止asp.net做其他事情.Response.End()抛出一个异常是否有一个非异常的方式我可以结束请求?
如果你想知道为什么我没有文件它的bc我告诉nginx通过http响应标头提供什么文件因此我在asp.net没有别的事情.Response.End抛出一个异常,它必须收集堆栈信息和所有这些.我显然不需要那个,从我过去的问题我知道抛出异常是昂贵的.那我该怎么办?
我正在使用新的路由功能编写asp.net 4.5应用程序.我有一个页面显示有关项目的一些信息.在Page_Load事件中,我检查路由数据(项目ID)和用户权限,如果事情是不正确(如ID是删除项),我用Response.RedirectToRoute送他们包装,马上回主页.不要通过GO,不要收200美元.
这是完全合理的,直到我尝试访问已删除的项目,而不是主页,我得到一个错误页面.我做了一些挖掘,发现即使在我使用之后RedirectToRoute(与标准Redirect方法不同),页面代码的其余部分仍继续执行,这至少看起来很浪费(因为我只是要扔掉结果)并抛出错误当必要的数据不存在时.
我做了一些更使挖掘和发现令人难以置信的邪恶是Response.End().它做了我需要的,但即使MSDN 页面告诉我,这Response.End是一个古老的诅咒语言的私生子,不适合看到光明的一天.主要的反对意见似乎是Response.End抛出一个异常,这对性能有害.我不是最有经验的开发人员,所以我完全不了解这个问题,但我很难相信抛出异常比加载整个网页更加昂贵.对于如此简单的任务,变通办法似乎相当复杂和过度,特别是因为大多数页面需要某种有效性检查.
在这种情况下我该怎么办?使用Response.End并请求原谅我的傲慢?凑齐一些丑陋的解决方法?或者我对这个问题的看法是错误的开始?我真的很想知道.
更新:现在我已经考虑了一点,我想知道我是否对这个问题有错误的观点.也许立即重定向不是对用户体验的最佳响应.我最好不要在面板中包装所有控件,并使用这样的东西?
Private Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init
'Validation Code
If notValid Then
ControlsPanel.Visible = false
ErrorPanel.Visible = true
End If
End Sub
Run Code Online (Sandbox Code Playgroud) Response.End();在asp.net中执行方法时,它抛出ThreadAbortException我在catch块中处理的内容,在内部catch块结束后我想执行一些其他代码,但它直接跳转到外部catch块.这是因为响应已经结束而且.net框架不执行任何进一步的代码?
protected void btn_click(object sender, EventArgs e)
{
try
{
string fileToDownload = MapPath(@"~\Sample.txt");
string fileToRead = MapPath(@"~\FileNotExist.txt");
try
{
//Section 1
try
{
// try to read the file which does not exist to raise the exception
StreamReader ss = new StreamReader(fileToRead);
}
catch (IOException IoEx)
{
// Just for sample exception
}
// Section 2 code block still execute because exception handled by upper try catch block
//Section 2
Response.Clear();
Response.ClearHeaders();
Response.AddHeader("Content-Disposition", "attachment;filename=SampleTemplate.txt");
Response.ContentType = …Run Code Online (Sandbox Code Playgroud) 请不要在此qustion上设置重复标志 - 它不是"为什么发生ThreadAbortException",它是关于"为什么w3wp.exe进程在ThreadAbortException之后终止".
假设我们有简单的Web应用程序,其代码示例如下:
protected void Page_Load(object sender, EventArgs e)
{
Response.Redirect("http://google.com");
}
Run Code Online (Sandbox Code Playgroud)
事实上这意味着什么(参见Response.End()被认为是有害的?):
protected void Page_Load(object sender, EventArgs e)
{
...response write some data...
System.Threading.Thread.CurrentThread.Abort();
}
Run Code Online (Sandbox Code Playgroud)
在我的计算机(Windows 10 Pro + IIS)上,此代码导致IIS池进程终止,错误代码为0x0(重定向不执行).在其他计算机(不是Windows 10)上,此代码仅生成ThreadAborted异常,但进程继续工作(重定向执行).
有人可以检查这个样本并解释发生了什么吗?
更新 这里有一些与此问题相关的Windows事件日志.
记录#1
发生未处理的异常,并终止该过程.
应用ID:/ LM/W3SVC/1/ROOT/AS
进程ID:6700
例外:System.Threading.ThreadAbortException
消息:线程正在中止.
StackTrace:位于System.Web.Hosting.PipelineRuntime.ProcessRequestNotification的System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr rootedObjectsPointer,IntPtr nativeRequestContext,IntPtr moduleData,Int32标志)的System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr,HttpContext context) (IntPtr rootedObjectsPointer,IntPtr nativeRequestContext,IntPtr moduleData,Int32 flags)
记录#2
Faulting application name: w3wp.exe, version: 10.0.10240.16384, time stamp: 0x559f3dad
Faulting module name: KERNELBASE.dll, version: 10.0.10240.16384, time stamp: 0x559f3b2a
Exception code: 0xe0434352
Fault …Run Code Online (Sandbox Code Playgroud) 是否有必要在Response.Redirect(url)之后调用Response.End()
更新
感谢所有的答案.因为有些答案说这是必要的而有些人说没有,我已经搜索了更多,并在msdn的评论中发现了以下内容:
重定向调用End,在完成时引发ThreadAbortException异常.
我们的应用程序的用户在白天至少两秒内下载一个附件.
以前的场景:
我们使用Response.End()在用户下载附件后中止与客户端的连接.由于我们遇到性能问题,我们开始记录异常,其中最重复的一个是线程中止异常.由于我们从Web服务获取附件,我们必须进行一些清理,并且我们在try-catch-finally块中进行了清理.经过一些研究,我已经理解,即使它在finally块中,也不会执行Response.End()之后的任何代码.是对的吗?
目前的情景:
我已经阅读了关于Response.End()的堆栈溢出中的线程是有害的,只有在真正需要它时才需要使用它,所以我决定使用HttpContext ....而不是CompleteRequest().使用此代码,可以完成所需的清理,但渲染的html将附加到下载的附件中.我尝试覆盖同一篇文章中提出的Render和RaisePostBackEvent,但问题仍然存在.有关如何解决此问题的任何想法都会有所帮助.
码:
HttpContext.Current.Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.AddHeader("Content-Disposition", "attachment; filename=" +
filename);
Response.AddHeader("Content-Length", fileContent.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.BinaryWrite(fileContent);
Response.Flush();
Run Code Online (Sandbox Code Playgroud) asp.net ×7
c# ×4
.net ×2
iis ×2
.net-4.6 ×1
asp.net-mvc ×1
httpresponse ×1
vb.net ×1
webforms ×1
windows-10 ×1