(这看起来与C# UnhandledException from another thread keeps looping非常相似,但我不是想在这里捕捉异常,只是有机会记录一些东西)
我有一些非常简单的C#代码,用于设置UnhandledException事件处理程序,然后抛出异常:
class Program
{
static void Main(string[] args)
{
AppDomain currentDomain = AppDomain.CurrentDomain;
//currentDomain.UnhandledException += new UnhandledExceptionEventHandler(currentDomain_UnhandledException);
currentDomain.UnhandledException += (sender, eventArgs) =>
{
var exception = (Exception) eventArgs.ExceptionObject;
Console.WriteLine("Unhandled exception: " + exception.Message);
};
throw new AccessViolationException("Bleurgh");
}
}
它的行为与我对控制台的期望一样:
Unhandled exception: Bleurgh
Unhandled Exception: System.AccessViolationException: Bleurgh
at UnhandledExceptions.Program.Main(String[] args) in c:\code\sandbox\UnhandledExceptions\UnhandledExceptions\Program.cs:line 20
但是当我尝试在Visual Studio中调试它时,它进入一个循环,进入事件处理程序,然后退出以重新抛出异常。
当我将处理程序表示为一个独特的静态方法时,会发生同样的事情。
任何想法发生了什么?
这是在Visual Studio 2010中。编辑:和.NET 4。
答案 0 :(得分:11)
这似乎是ExceptionAssistant的特定行为。当您继续时,助手会将调用堆栈展开到抛出异常的位置 - 这会导致异常被重新抛出。我假设这是允许您进行更改,以避免异常。
如果在Tools \ Options \ Debugger \ General下取消选中“在未处理的异常上展开调用堆栈”,那么它只会表现为独立进程的行为,并且您将看到进程终止。
答案 1 :(得分:1)
这是调试器的工作方式,或者我们应该说是“功能”。如果进程是由调试器创建的(F5),那么调试器将阻止进程终止,并指向可能导致进程终止的代码行。那些“未处理的异常”实际上是由调试器处理的,因此执行永远不会到达您的代码。
如果在创建进程后将调试器附加到进程(Ctrl + F5,然后附加),则调试器最终将到达未处理的异常“处理程序”,但在退出处理程序后,它仍将阻止进程终止,并带来你回到发生异常的地步。