为什么未处理的异常在调试时不会终止进程?

时间:2009-10-08 10:30:19

标签: c# .net visual-studio debugging unhandled-exception

这是我之前多次注意到的一种行为,我想知道背后的原因。如果在(Visual Studio 2008)调试器下运行以下程序,则无论您多久继续调试,调试器都会在throw语句中保持中断。你必须停止调试才能走出去。我希望调试器中断一次然后如果你在没有调试器的情况下运行程序就会终止进程。是否有人知道这种行为的充分理由?

using System;

namespace ExceptionTest
{
   static internal class Program
   {
      static internal void Main()
      {
         try
         {
            throw new Exception();
         }
         catch (Exception exception)
         {
            Console.WriteLine(exception.Message);

            // The debuger  will never go beyond
            // the throw statement and terminate
            // the process. Why?
            throw;
         }
      }
   }
}

3 个答案:

答案 0 :(得分:2)

单步执行未处理的异常将终止该进程 - 它可能只是为了阻止您在不打算时意外终止该进程。

如果在其他地方处理异常(例如在通用的外部try-catch块中),那么您将能够跳过异常,调试器将把您带到处理它的地方。

答案 1 :(得分:1)

如果要终止该过程,请使用“停止”按钮。有时停止应用程序肯定是有用的。调试器不坚持杀死应用程序的原因是程序员可能想要在抛出异常的上下文中检查程序的状态和/或以程序可以继续的方式“轻推”事物。值得注意的是调试器陷阱发生在终结器运行之前;这使得有可能检查在最终确定期间会被破坏的程序状态的各个方面。

另请注意,可能会有一个异常会触发“未捕获的异常”调试器陷阱,但不会终止该程序。例如,人们可以做类似的事情:

Class exTest
    Class myException
        Inherits Exception
        Sub New(ByVal innerException As Exception)
            MyBase.new("Wrapped Exception", innerException)
        End Sub
    End Class
    Shared Function CopyArg1ToArg2AndReturnFalse(Of T)(ByVal arg1 As T, ByRef arg2 As T) As Boolean
        arg2 = arg1
        Return False
    End Function
    Shared Sub testIt()
        Dim theException As Exception = Nothing
        Try
            Try
                Throw New ApplicationException
            Catch ex As Exception When CopyArg1ToArg2AndReturnFalse(ex, theException)
                Throw
            Finally
                If theException IsNot Nothing Then Throw New myException(theException)
            End Try
        Catch ex As myException
            Debug.Print("Exception: " & ex.InnerException.ToString)
        End Try
    End Sub
End Class

在没有人要捕获ApplicationException的异常触发任何Finally子句之前,系统确定。但实际情况是,如果抛出异常,则Finally子句将通过抛出自己的新异常来阻止该特定异常的转义 - 被捕获的新异常。

这种技巧对于在一些内部级别捕获和处理某些异常(不破坏用户体验)的情况下进行调试可能很有用,而其他异常将被困在外层(例如,发出错误消息)。仅存在于外层的异常将在它们发生时生成调试器陷阱,而那些陷入内层的异常将允许程序继续运行。

答案 2 :(得分:0)

你无法跨越一个异常,即在没有被处理的情况下一直冒泡到'顶部' 如果你真的需要它,试试这个:

static internal void Main()
        {
            try
            {
                throw new Exception();
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception.Message);

                // The debuger  will never go beyond
                // the throw statement and terminate
                // the process. Why?
                Environment.FailFast("Oops");
                throw;
            }
        }