在 Visual Studio 中使用调试器管理异常Manage exceptions with the debugger in Visual Studio

异常是执行程序时发生的错误状态的指示。An exception is an indication of an error state that occurs while a program is being executed. 你可以告知调试器在遇到哪些异常或异常集合时中断,以及希望调试器在哪个时间点中断(即在调试器中暂停)。You can tell the debugger which exceptions or sets of exceptions to break on, and at which point you want the debugger to break (that is, pause in the debugger). 调试器中断时,会显示引发异常的位置。When the debugger breaks, it shows you where the exception was thrown. 你还可以添加或删除异常。You can also add or delete exceptions. 在 Visual Studio 中打开一个解决方案后,使用“调试”>“Windows”>“异常设置”打开异常设置”窗口 。With a solution open in Visual Studio, use Debug > Windows > Exception Settings to open the Exception Settings window.

提供响应最重要异常的处理器。Provide handlers that respond to the most important exceptions. 如果需要知道如何为异常添加处理器,请参阅通过编写更好的 C# 代码来修复 bugIf you need to know how to add handlers for exceptions, see Fix bugs by writing better C# code. 此外,还可了解如何将调试器配置为在引发某些异常时始终中断执行。Also, learn how to configure the debugger to always break execution for some exceptions.

异常发生时,调试程序将一条异常消息写入到“输出”窗口 。When an exception occurs, the debugger writes an exception message to the Output window. 它可能会在以下情况下中断执行:It may break execution in the following cases when:

  • 引发未处理的异常。An exception is thrown that isn't handled.
  • 调试器配置为在调用任何处理器之前中断执行。The debugger is configured to break execution before any handler is invoked.
  • 你设置了仅我的代码,并且调试器配置为引发任何未在用户代码中进行处理的异常时中断。You have set Just My Code, and the debugger is configured to break on any exception that isn't handled in user code.

备注

ASP.NET 有一个顶级异常处理程序,可以在浏览器中显示错误页。ASP.NET has a top-level exception handler that shows error pages in a browser. 除非启用“仅我的代码”,否则它不会中断执行 。It doesn't break execution unless Just My Code is turned on. 有关示例,请参阅下面的告知调试器在遇到用户未处理的异常时继续执行For an example, see Tell the debugger to continue on user-unhandled exceptions below.

备注

在 Visual Basic 应用程序中,调试程序将所有错误作为异常进行管理,即使使用出错时样式错误处理程序也是如此。In a Visual Basic application, the debugger manages all errors as exceptions, even if you use On Error-style error handlers.

告知调试器在引发异常时中断。Tell the debugger to break when an exception is thrown

调试器可能会在引发异常时中断执行,这让你有机会在调用处理器之前对异常进行检查。The debugger can break execution at the point where an exception is thrown, so you may examine the exception before a handler is invoked.

在“异常设置”窗口中(“调试”>“Windows”>“异常设置”),展开一个异常类别的节点,例如“公共语言运行时异常” 。In the Exception Settings window (Debug > Windows > Exception Settings), expand the node for a category of exceptions, such as Common Language Runtime Exceptions. 然后选中该类别中特定异常的复选框,如 System.AccessViolationException 。Then select the check box for a specific exception within that category, such as System.AccessViolationException. 还可以选择整个类别的异常。You can also select an entire category of exceptions.

已选中 AccessViolationExceptionChecked AccessViolationException

提示

可以使用“异常设置”工具栏中的“搜索”窗口查找特定异常,也可以使用搜索筛选特定命名空间(例如 System.IO) 。You can find specific exceptions by using the Search window in the Exception Settings toolbar, or use search to filter for specific namespaces (such as System.IO).

如果在“异常设置”窗口中选择异常,则调试器会在引发异常(无论是否已处理)时中断执行 。If you select an exception in the Exception Settings window, debugger execution will break wherever the exception is thrown, no matter whether it's handled. 此时,该异常被称为第一次机会异常。Now the exception is called a first chance exception. 以下是几个应用场景示例:For example, here are a couple of scenarios:

  • 在下面的 C# 控制台应用程序中,Main 方法在 try/catch 块内引发“AccessViolationException” 。In the following C# console application, the Main method throws an AccessViolationException inside a try/catch block.

    static void Main(string[] args)
    {
        try
        {
            throw new AccessViolationException();
            Console.WriteLine("here");
        }
        catch (Exception e)
        {
            Console.WriteLine("caught exception");
        }
        Console.WriteLine("goodbye");
    }
    

    如果在“异常设置”中选中了 AccessViolationException,则在调试器中运行此代码时将在 throw 行上中断执行 。If you have AccessViolationException checked in Exception Settings, execution will break on the throw line when you run this code in the debugger. 然后可以继续执行。You can then continue execution. 控制台应显示这两行:The console should display both lines:

    caught exception
    goodbye
    

    但它没有显示 here 行。but it doesn't display the here line.

  • C# 控制台应用程序引用了一个类库,该类库中的类具有两个方法。A C# console application references a class library with a class that has two methods. 一个方法引发异常并对其进行处理,而另一个方法引发同一异常但不处理。One method throws an exception and handles it, while a second method throws the same exception but doesn't handle it.

    public class Class1
    {
        public void ThrowHandledException()
        {
            try
            {
                throw new AccessViolationException();
            }
            catch (AccessViolationException ave)
            {
                Console.WriteLine("caught exception" + ave.Message);
            }
        }
    
        public void ThrowUnhandledException()
        {
            throw new AccessViolationException();
        }
    }
    

    以下是控制台应用程序的 Main() 方法:Here's the Main() method of the console application:

    static void Main(string[] args)
    {
        Class1 class1 = new Class1();
        class1.ThrowHandledException();
        class1.ThrowUnhandledException();
    }
    

    如果在“异常设置”中选中了AccessViolationException,则在调试器中运行此代码时将在 ThrowHandledException() 和 ThrowUnhandledException() 中的 throw 行上中断执行 。If you have AccessViolationException checked in Exception Settings, execution will break on the throw line in both ThrowHandledException() and ThrowUnhandledException() when you run this code in the debugger.

要将异常设置还原为默认值,请选择“将列表还原为默认设置”按钮 :To restore the exception settings to the defaults, choose the Restore the list to the default settings button:

还原“异常设置”中的默认值Restore defaults in Exception Settings

告知调试器在遇到用户未处理的异常时继续执行Tell the debugger to continue on user-unhandled exceptions

如果使用仅我的代码调试 .NET 或 JavaScript 代码,则可以告知调试器在遇到未在用户代码中进行处理但在其他地方进行了处理的异常时不要执行中断操作。If you are debugging .NET or JavaScript code with Just My Code, you can tell the debugger to prevent breaking on exceptions that aren't handled in user code but are handled elsewhere.

  1. 在“异常设置”窗口中,右键单击列标签打开快捷菜单,然后选择“显示列”>“其他操作” 。In the Exception Settings window, open the shortcut menu by right-clicking a column label, and then select Show Columns > Additional Actions. (如果已禁用“仅我的代码”,将看不到此命令。 )将显示名为“其他操作”的第三列 。(If you've turned off Just My Code, you won't see this command.) A third column named Additional Actions appears.

    “其他操作”列Additional Actions column

    对于在此列中显示“在遇到未在用户代码中进行处理的异常时继续执行”的异常,如果调试器遇到未在用户代码中进行处理但在其他地方进行了处理的异常,则将继续执行 。For an exception that shows Continue when unhandled in user code in this column, the debugger continues if that exception isn't handled in user code but is handled externally.

  2. 要更改特定异常的此设置,请选择异常,右键单击以显示快捷菜单,然后选择“在遇到未在用户代码中进行处理的异常时继续执行” 。To change this setting for a particular exception, select the exception, right-click to show the shortcut menu, and select Continue When Unhandled in User Code. 你还可以更改整个异常类别的设置,如整个“公共语言运行时”异常。You may also change the setting for an entire category of exceptions, such as the entire Common Language Runtime exceptions).

    “在遇到未在用户代码中进行处理的异常时继续执行”设置Continue when unhandled in user code setting

例如,ASP.NET Web 应用程序通过将异常转换为 HTTP 500 状态代码来处理异常(ASP.NET Web API 中的异常处理),该方法可能无法帮助你确定异常的来源。For example, ASP.NET web applications handle exceptions by converting them to an HTTP 500 status code (Exception handling in ASP.NET Web API), which may not help you determine the source of the exception. 在下面的示例中,用户代码对引发 String.Format()FormatException进行调用。In the example below, the user code makes a call to String.Format() that throws a FormatException. 异常中断如下所示:Execution breaks as follows:

在遇到用户未处理的异常中断Breaks on user-unhandled exception

添加和删除异常Add and delete exceptions

可以添加和删除异常。You can add and delete exceptions. 要从某个类别中删除某一异常类型,请选择该异常,然后在“异常设置”工具栏上,选择“从列表中删除所选异常”按钮(减号) 。To delete an exception type from a category, select the exception, and choose the Delete the selected exception from the list button (the minus sign) on the Exception Settings toolbar. 你也可以右键单击异常,然后从快捷菜单中选择“删除” 。Or you may right-click the exception and select Delete from the shortcut menu. 删除异常与取消选中异常的效果一样,即调试器在引发该异常时不会中断。Deleting an exception has the same effect as having the exception unchecked, which is that the debugger won't break when it's thrown.

要添加异常,请执行以下操作:To add an exception:

  1. 在“异常设置”窗口中,选择其中一个异常类别(例如“公共语言运行时”) 。In the Exception Settings window, select one of the exception categories (for example, Common Language Runtime).

  2. 选择“向所选类别添加异常”按钮(加号) 。Choose the Add an exception to the selected category button (the plus sign).

    “向所选类别添加异常”按钮Add an exception to the selected category button

  3. 键入异常的名称(例如 System.UriTemplateMatchException )。Type the name of the exception (for example, System.UriTemplateMatchException).

    键入异常名称Type the exception name

    异常随即添加到列表(按字母顺序),并自动选中。The exception is added to the list (in alphabetical order) and automatically checked.

要向“GPU 内存访问异常”、“JavaScript 运行时异常”或“Win32 异常”类别添加异常,请包括错误代码和说明。To add an exception to the GPU Memory Access Exceptions, JavaScript Runtime Exceptions, or Win32 Exceptions categories, include the error code and the description.

提示

请检查你的拼写!Check your spelling! “异常设置”窗口不会检查是否存在添加的异常 。The Exception Settings window doesn't check for the existence of an added exception. 因此,如果键入 Sytem.UriTemplateMatchException,则将获得该异常的条目(而不是“System.UriTemplateMatchException”的条目) 。So if you type Sytem.UriTemplateMatchException, you'll get an entry for that exception (and not for System.UriTemplateMatchException).

异常设置保留在解决方案的 .suo 文件中,因此适用于特定解决方案。Exception settings are persisted in the solution's .suo file, so they apply to a particular solution. 无法跨解决方案重用特定异常设置。You can't reuse specific exception settings across solutions. 此时,仅保留添加的异常,而不保留删除的异常。Now only added exceptions are persisted; deleted exceptions aren't. 你可以添加一个异常,然后关闭并重新打开解决方案,该异常仍然存在。You may add an exception, close and reopen the solution, and the exception will still be there. 但是,如果删除一个异常,然后关闭/重新打开解决方案,异常将消失。But if you delete an exception and close/reopen the solution, the exception will reappear.

“异常设置” 窗口在 C# 中支持通用异常类型,但在 Visual Basic 中不支持。The Exception Settings window supports generic exception types in C# but not in Visual Basic. 要对类似 MyNamespace.GenericException<T>的异常执行中断操作,则必须将异常作为 MyNamespace.GenericException`1添加。To break on exceptions like MyNamespace.GenericException<T>, you must add the exception as MyNamespace.GenericException`1. 也就是说,如果已经创建了类似以下代码的异常:That is, if you've created an exception like this code:

public class GenericException<T> : Exception
{
    public GenericException() : base("This is a generic exception.")
    {
    }
}

则可以按照上一个过程将异常添加到“异常设置”窗口 :You can add the exception to Exception Settings using the previous procedure:

添加常见异常adding generic exception

向异常添加条件Add conditions to an exception

使用“异常设置”窗口对异常设置条件 。Use the Exception Settings window to set conditions on exceptions. 当前支持的条件包括要包括在异常中或排除在异常外的模块名称。Currently supported conditions include the module name(s) to include or exclude for the exception. 通过将模块名称设置为条件,可以选择仅在某些代码模块遇到异常时中断执行。By setting module names as conditions, you can choose to break for the exception only on certain code modules. 你还可以选择在特定的模块遇到异常时不要中断执行。You may also choose to avoid breaking on particular modules.

备注

Visual Studio 2017Visual Studio 2017 开始,支持向异常添加条件。Adding conditions to an exception is supported starting in Visual Studio 2017Visual Studio 2017.

要添加异常条件,请执行以下操作:To add conditional exceptions:

  1. 在“异常设置”窗口中选择“编辑条件”按钮,或右键单击异常并选择“编辑条件” 。Choose the Edit conditions button in the Exception Settings window, or right-click the exception and choose Edit Conditions.

    异常的条件Conditions for an exception

  2. 要向异常添加额外的所需条件,请为每个新条件选择“添加条件” 。To add extra required conditions to the exception, select Add Condition for each new condition. 将显示其他条件行。Additional condition lines appear.

    异常的额外条件Extra conditions for an exception

  3. 对于每个条件行,键入模块的名称,然后将比较运算符列表更改为“等于”或“不等于” 。For each condition line, type the name of the module, and change the comparison operator list to Equals or Not Equals. 你可以在名称中指定通配符 (\*),以指定多个模块 。You may specify wildcards (\*) in the name to specify more than one module.

  4. 如果需要删除条件,请选择条件行末尾的 X 。If you need to delete a condition, choose the X at the end of the condition line.

请参阅See also