调试UnhandledException事件时,为什么Visual Studio会循环

时间:2013-12-11 11:01:53

标签: c# visual-studio-2010 c#-4.0 unhandled-exception

(这看起来与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。

2 个答案:

答案 0 :(得分:11)

这似乎是ExceptionAssistant的特定行为。当您继续时,助手会将调用堆栈展开到抛出异常的位置 - 这会导致异常被重新抛出。我假设这是允许您进行更改,以避免异常。

如果在Tools \ Options \ Debugger \ General下取消选中“在未处理的异常上展开调用堆栈”,那么它只会表现为独立进程的行为,并且您将看到进程终止。

答案 1 :(得分:1)

这是调试器的工作方式,或者我们应该说是“功能”。如果进程是由调试器创建的(F5),那么调试器将阻止进程终止,并指向可能导致进程终止的代码行。那些“未处理的异常”实际上是由调试器处理的,因此执行永远不会到达您的代码。

如果在创建进程后将调试器附加到进程(Ctrl + F5,然后附加),则调试器最终将到达未处理的异常“处理程序”,但在退出处理程序后,它仍将阻止进程终止,并带来你回到发生异常的地步。