当我运行Response.Redirect()时,为什么会抛出异常?

6

我正在学习ASP.NET,关注的是QueryStrings。

我正在看一个例子,其中一个按钮与重定向调用相连:

    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        try
        {
            //throws ThreadAbortException: "Thread was being aborted"
            Response.Redirect("Form2.aspx");
        }
        catch (Exception Ex)
        {
            System.Diagnostics.Debug.WriteLine(Ex.Message);
        }
    }

为什么会在这里抛出ThreadAbortException?这是正常的吗?我需要采取什么措施吗?通常情况下,异常并不是一件好事,所以当我看到这个异常时感到很惊讶。

https://dev59.com/aEjSa4cB1Zd3GeqPDjke - Mauricio Scheffer
9个回答

15

这是有意设计的。这篇KB文章描述了这种行为(也适用于Request.End()Server.Transfer()方法)。

对于Response.Redirect(),存在一种重载形式:

Response.Redirect(String url, bool endResponse)
如果你传入了 endResponse=false,那么异常不会被抛出(但运行时会继续处理当前请求)。
如果 endResponse=true(或者使用没有布尔参数的重载),则异常会被抛出,并且当前请求将立即被终止。

2
我怀疑这可能并不是“按设计要求”,也许只是他们设计的不幸后果?;) - MedicineMan
2
“按设计”并不意味着所选择的设计是完美的;-) - M4N
尽管将false传递给第二个参数,我仍然遇到这个问题,相同的二进制文件在同一服务器上的另一个网站上可以正常工作,我检查了应用程序池设置,它们是匹配的。 - fahadash

3

这是正常的。 Server.Transfer()也会抛出同样的异常。

这是因为在内部,两种方法都调用Response.End(),该方法会立即中止当前请求处理。Rick Strahl有一篇非常好的博客文章分析了为什么几乎没有什么可以避免这些异常。


3

Response.Redirect在内部调用了Response.End,因此会抛出异常,应改用以下方法:

Response.Redirect(url, false);

2

这是正常的,因为这就是预期发生的事情。基本上,当响应被设置为重定向时,ASP.NET 期望您已经完全处理完请求。它会中止线程以防止其他任何处理发生(基本上它为您调用了Response.End,并抛出异常)。

我认为这有点滥用异常,但这就是它的工作方式。如果您想要防止这种情况发生,可以使用具有第二个参数的重载(并传递false),但如果这样做,请确保没有其他内容尝试写入响应!


1

我相信您需要遵循此 KB 文章中的说明。Response.Redirect 调用 Response.End(),除非您使用了专门用于避免此行为的重载。一旦响应已结束,就不会发生任何进一步的操作,因此 TA 等。

http://support.microsoft.com/kb/312629


1

0
调用只接受URL参数的Redirect()重载方法也会导致调用Response.End(),这会抛出ThreadAbort异常以确保在页面/用户控件中重定向后不运行其他代码。
您不应该捕获此异常...您应该在代码中忽略它或使用带有布尔值参数的Redirect()重载方法,该参数指示是否在重定向后继续处理请求。

0
是的。我在那些后面编写了一个“退出子程序”代码,但我知道它没有被执行。
我想如果你愿意,你可以吃掉这个异常,然后继续做更多的事情,但我不建议这样做。

0

这里已经有很多合理的答案了。还有一个值得注意的点是,线程中止异常是那些你可以捕获并编写代码对抗的罕见异常之一,但你无法抑制它。无论你做什么,在任何try/catch/finally块结束时,它都会自动重新引发。

如果你决定接受这个异常,你应该确保你的健康监控允许这种情况,并且不将其报告为问题,这样你就不会被困在一群非技术经理面前,试图解释为什么你的网站会抛出这么多线程中止异常。(我曾经有一个经理相信所有这些线程中止都会留下一堆问题,当然这与线程中止的意图完全相反。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接