【问题标题】:Why does an unhandled exception not terminate a process while debugging?为什么调试时未处理的异常不会终止进程?
【发布时间】:2009-10-08 10:30:18
【问题描述】:
这是我之前多次注意到的行为,我想知道其背后的原因。如果您在 (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;
}
}
}
}
【问题讨论】:
标签:
c#
.net
visual-studio
debugging
unhandled-exception
【解决方案1】:
跳过未处理的异常会终止进程——它可能只是为了阻止你在你不打算的时候意外终止进程。
如果异常在其他地方处理(例如在通用外部 try-catch 块中),那么您将能够跳过异常,调试器会将您带到处理它的地方。
【解决方案2】:
如果您想终止进程,请使用“停止”按钮。有时停止应用程序肯定是有用的。调试器不坚持终止应用程序的原因是程序员可能希望在抛出异常的上下文中检查程序的状态和/或以程序可以继续的方式“轻推”事物。值得注意的是,调试器陷阱发生在终结器运行之前;这样就可以检查在完成过程中会被破坏的程序状态的各个方面。
另请注意,可能有一个异常会触发“未捕获的异常”调试器陷阱,但不会终止程序。例如,可以执行以下操作:
课堂考试
类 myException
继承异常
Sub New(ByVal innerException 作为异常)
MyBase.new("包装异常", innerException)
结束子
结束类
共享函数 CopyArg1ToArg2AndReturnFalse(Of T)(ByVal arg1 As T, ByRef arg2 As T) As Boolean
参数 2 = 参数 1
返回假
结束功能
共享子 testIt()
将异常调暗为异常 = 无
尝试
尝试
抛出新的应用程序异常
当 CopyArg1ToArg2AndReturnFalse 时将 ex 捕获为异常(例如,theException)
扔
最后
If theException IsNot Nothing Then Throw New myException(theException)
结束尝试
捕获前作为 myException
Debug.Print("异常:" & ex.InnerException.ToString)
结束尝试
结束子
结束类
系统在异常触发任何 finally 子句之前确定没有人会捕获 ApplicationException。然而,碰巧的是,如果确实抛出了异常,Finally 子句将通过抛出它自己的新异常来防止该特定异常逃逸——一个将被捕获的新异常。
在某些异常将在内部级别被捕获和处理(不会破坏用户体验)而其他异常将在外部级别(例如,提出错误消息)被捕获的情况下,此技巧可能对调试很有用。仅在外层捕获的异常在发生时会生成调试器陷阱,而在内层捕获的异常将允许程序继续运行。
【解决方案3】:
你不能跳过一个冒泡到“顶部”而不被处理的异常
如果你真的需要,试试这个:
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;
}
}