在“using {}”中使用Response.Redirect("")

4
假设以下代码:
using (SqlConnection conn = new SqlConnection(connectionString))
{
   ...
   using (SqlCommand comm = new SqlCommand(...))
   {
      .. do stuff ..
      if(condition) Response.Redirect("somepage.aspx");

   }
}

Response.Redirect()会退出using块并导致所有连接被处理吗?
或者,有没有一种不会导致处理的方法来退出using块?
编辑:我不想在没有处理的情况下退出。我想知道是否有任何可能导致它无法工作的问题。 - 当然,除了崩溃的情况,但是在那种情况下,我相信所有对象都会以“硬”的方式被处理。
我已经接受了一个答案,基本上是说“我不知道”,但这是一个非常好的研究“我不知道”。
暂时来说,我会假设Response.Redirect会中止using语句和代码,并根据此进行编码 - 直到被证明是另外一种情况。

答案不正确,因为MSDN文档在这方面也是错误的。引用的文本已从MSDN文档中删除。我正在对答案进行负投票。 - Icarus
7个回答

6
http://msdn.microsoft.com/en-us/library/aa973248.aspxhttp://msdn.microsoft.com/en-us/magazine/cc163298.aspx

调用Response.Redirect不会执行finally块(以及像C#“using”语句这样的特定于语言的关键字)。因此,在进行任何重定向或处理转移之前,必须处理这些对象。

但从http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception.aspx中:

当调用Abort方法销毁线程时,公共语言运行时引发ThreadAbortException。ThreadAbortException是一种特殊的异常,可以捕获,但它将在catch块结束时自动再次引发。 当引发此异常时,运行时会在结束线程之前执行所有finally块。由于线程可以在finally块中执行无限计算,或者调用Thread..::.ResetAbort取消中止,因此不能保证线程将永远结束。如果要等待已中止的线程结束,可以调用Thread..::.Join方法。 Join是一个阻塞调用,直到线程实际停止执行才会返回。

听起来需要进行测试...


1
因此,我建议在 using 块之外执行 Page.Transfer。重构您的代码以在 using 块完成后测试条件标志。 - Kimoz

2

问:或者,有没有任何方法可以退出using块而不会导致处理?

答:没有。

了解更多信息,请参见:C#“Using”语法


2

Response.Redirect终止了服务器端的执行。

在正常的执行过程中,退出using块会触发对象的处理。当进程关闭、计算机关闭、线程被中止等情况发生时,可能会违反此规则。但在正常的执行过程中不会出现这种情况。

可以看一下Server.Transfer。它可能有助于实现您的目标。


2

来自http://msdn.microsoft.com/en-us/library/aa973248.aspx

调用Response.Redirect不会执行finally块。因此,在进行任何重定向或处理转移之前,必须处置对象。

是的,它并没有直接涉及Using语句,但这是一种常见的编程实践需要注意。此外,该文章提到了SharePoint,但由于SP是建立在ASP.NET 2.0上的,因此我认为它仍然相关。


MSDN文档有误。引用的文本已从文档中删除。请参阅此其他问题:https://dev59.com/OmfWa4cB1Zd3GeqPgmV5 - Icarus

0

所有的using语句都是基于作用域的。因此,无论您如何退出函数,在该点处基于堆栈的所有内容都将从using中清除。异常、返回等也是如此。

我不知道有什么方法可以防止它触发,即使您出于某种原因想要这样做。


我不想阻止处理。我想知道任何可能出现的问题。 - Chris Cudmore

0

为什么你想在不进行处理的情况下退出 using 块呢?这不是 using 块的设计初衷。

如果你愿意,可以不使用它,但我不建议这样做。


0

以下代码有什么问题:

using(SqlCommand comm = new SqlCommand(...))
{
...
if(condition)
{

//我们已经判断了这是 true,所以我们不再需要 using
//清理代码

break;
//或者 continue; 如果那更好的话
}
//在 "if" 不成立的情况下执行的代码。
}

Response.Redirect(page);"

?


一个break语句并不能保护你的对象免于被销毁。 - jop
但是我会明确地留下一个注释点,指示应该放置处理代码的位置。 - One Monkey
1
哦,我明白你的意思了。我的尝试是除非他完成了使用块,否则不让他重定向。显然,在处理完毕后,他才想要重定向。我假设他在完成之后仍可能想要重定向。 - One Monkey
因此,设置一个标志,在使用块之后进行重定向。 - Chris Cudmore
是的,那也是我的另一个想法,但我认为这个例子足以推动那个方向。只是想帮忙。也许将来不会再打扰了。 - One Monkey

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