【问题标题】:Exception Handling - line skipped and sqle is null异常处理 - 已跳过行且 sqle 为空
【发布时间】:2010-10-26 13:21:01
【问题描述】:

IDE = VS7 或 2002

大家好,我有一个非常奇怪的问题。代码似乎没有按预期执行。我正在通过调试器运行它,它的表现真的很奇怪。

我已确定虚拟目录使用的是 ASP.NET 1.0.3705。

代码如下,我解释了调试器显示的 cmets 中的执行步骤:

try
{
    objConnection.Open();  // STARTS HERE
    objCommand.ExecuteNonQuery();  // DOES NOT THROW EXCEPTION
    int c = 0;  // THIS LINE IS EXECUTED
}
catch (SqlException sqle)
{

    LogError();  // THIS LINE IS NOT EXECUTED
    throw sqle;  // THIS LINE IS EXECUTED AFTER THE int c = 0; 
                 // sqle IS NULL
                 // EXCEPTION IS NOT CAUGHT AND 
                 // EXECUTION CONTINUES IN FINALLY BLOCK
}
finally
{
    // EXECUTES AS EXPECTED FROM HERE ON OUT,
    // AS THOUGH THE throw sqle; DID NOT HAPPEN.
    if (objConnection.State == ConnectionState.Open) objConnection.Close();
}

以前有没有人经历过这种奇怪的行为?知道如何解决吗?我可能会广泛地改变方法,但我仍然想知道为什么会这样。

我怀疑由于 sqle 为 null,这就是 throw 未按预期运行的原因。但是为什么我们一开始就跳进了这个代码块呢?

我已经多次重新加载它,保存并重建,并使用调试器执行并多次观察此行为。

感谢大家的帮助!

一切顺利,

格雷厄姆

【问题讨论】:

  • itsmatt 和 David,据我所知,问题出在调试器上。我按照大卫的建议使用 Debug.WriteLine()。我有另一段代码遇到了类似的问题。应该发生异常但没有发生。调试器查看了 if 语句并决定它应该在其中运行代码 - 这应该会导致异常。查看 WriteLine 语句,我可以看到 if 语句中的代码块实际上并未运行。调试器认为代码将如何执行与它实际执行的方式之间存在差异。感谢您的帮助
  • 很高兴听到这个消息。听起来调试器正在查看的已编译程序集比源代码旧。您可以尝试删除 /bin 文件夹并再次重建项目。

标签: c# exception .net-1.0


【解决方案1】:

等等..您的代码没有抛出异常,而您想知道为什么它不执行 catch 块?

编辑(引用您的评论):

这听起来真的很难相信。我从未听说过 catch 块内的实际异常为 null 的情况,正如您已经提到的那样,catch 块内的第一行没有执行,我认为这指向了根本没有异常的方向。

您是否尝试使用老式调试技术 (Debug.WriteLine) 并跳过调试器来检查程序流程?

我的假设是您正在查看引发异常的错误位置..或者根本没有异常。

【讨论】:

  • 即使没有抛出异常,也会执行一个 catch。在那个 catch 中有一个 throw [我没有写这段代码] 并且 throw 行执行但是异常为 null 并且它没有被捕获。
  • itsmatt 和 David,据我所知,问题出在调试器上。我按照大卫的建议使用 Debug.WriteLine()。我有另一段代码遇到了类似的问题。应该发生异常但没有发生。调试器查看了 if 语句并决定它应该在其中运行代码 - 这应该会导致异常。查看 WriteLine 语句,我可以看到 if 语句中的代码块实际上并未运行。调试器认为代码将如何执行与它实际执行的方式之间存在差异。感谢您的帮助
  • IIRC,那个版本的调试器有问题。看起来好像你正在执行一行代码,然后它会跳过行,或者做其他奇怪的事情。我认为它在以后的版本中已修复。您可以通过清除 bin 文件夹并重建来解决它。
【解决方案2】:

很奇怪。我不确定您的代码发生了什么,但我看到的一件事是使用:

catch (SqlException sqle)
{

    LogError();  // THIS LINE IS NOT EXECUTED
    throw sqle;  // THIS LINE IS EXECUTED AFTER THE int c = 0; 
                 // sqle IS NULL
                 // EXCEPTION IS NOT CAUGHT AND 
                 // EXECUTION CONTINUES IN FINALLY BLOCK
}

你想写:

catch (SqlException sqle)
{

    LogError(); 
    throw; 
}

重新抛出异常。

【讨论】:

  • 第一个版本完全没有错。你只是在杀死堆栈跟踪。
  • 我并没有说这是错误的,但是通常查看完整的堆栈跟踪肯定会更有用。感谢您指出了这一点。我忘了把它放在我的评论中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-31
  • 2015-11-03
  • 2015-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多