代码之家  ›  专栏  ›  技术社区  ›  Daniel Brückner Pradip

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

  •  3
  • Daniel Brückner Pradip  · 技术社区  · 15 年前

    这是我以前注意到过好几次的行为,我想知道背后的原因。如果在(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 回复  |  直到 15 年前
        1
  •  2
  •   Justin    15 年前

    跳过未处理的异常将终止进程-这可能只是为了阻止您在无意中终止进程。

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

        2
  •  1
  •   supercat    13 年前

    如果要终止进程,请使用“停止”按钮。有时,停止应用程序肯定很有用。调试器不坚持终止应用程序的原因是程序员可能希望在抛出异常和/或“轻推”事件的上下文中检查程序的状态,以便程序可以继续。值得注意的是,调试器陷阱发生在终结器运行之前;这使得检查程序状态的某些方面成为可能,这些方面将在最终确定过程中被破坏。

    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
    

    在异常触发任何Finally子句之前,系统确定没有人将捕获ApplicationException。但是,如果确实抛出了异常,那么Finally子句将通过抛出自己的新异常来防止特定异常逃逸——一个

    在某些异常将被捕获并在内部级别处理(而不中断用户体验)而其他异常将被捕获并在外部级别处理(例如,显示错误消息)的情况下,此技巧可能对调试非常有用。仅在外部级别捕获的异常将在发生时生成调试器陷阱,而在内部级别捕获的异常将允许程序继续。

        3
  •  0
  •   Jan Bannister    15 年前

    如果异常一直冒泡到“顶部”,而未得到处理,则无法跳过该异常

    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;
                }
            }