现已发布!阅读关于 11 月的新功能和修复。

调试

您可以使用 Microsoft C# 扩展在 Visual Studio Code 中调试 C# 应用程序。

运行和调试

C# 扩展和 C# Dev Kit 提供了多种运行和调试 C# 应用程序的方法。

要在不使用 C# Dev Kit 的情况下运行和调试,请参阅 Microsoft C# 扩展的 GitHub 页面,获取文档。

使用 F5 调试

安装 C# Dev Kit 扩展且调试视图中没有可供选择的调试配置时,可以通过打开一个 .cs 文件,然后按 F5 来开始调试项目。调试器将自动查找您的项目并开始调试。如果您有多个项目,它将提示您要开始调试哪个项目。

您还可以从 VS Code 侧边栏的 运行和调试 视图启动调试会话。有关详细信息,请参阅在 VS Code 中调试

Debugging using Run and Debug

使用解决方案资源管理器调试

安装 C# Dev Kit 扩展后,当您在解决方案资源管理器中右键单击您的项目时,会出现一个 调试 上下文菜单。

有三个选项

  • 启动新实例 - 这将启动您的项目并附加调试器。
  • 开始但不调试 - 这将运行您的项目,但不附加调试器。
  • 步入新实例 - 这将启动您的项目并附加调试器,但会在代码的入口点停止。

Debugging using Solution Explorer

使用命令面板调试

安装 C# Dev Kit 扩展后,您还可以通过命令面板 ⇧⌘P(Windows、Linux Ctrl+Shift+P,使用 调试:选择并启动调试 命令开始调试。

注意:这会在您的调试下拉列表中添加一个启动配置项。

Debugging using Command Palette

使用动态(内存中)启动配置调试

安装 C# Dev Kit 扩展后,您可以创建动态启动配置。创建它们的方式取决于您的项目是否具有现有的 launch.json 文件。

现有 launch.json

如果您有现有的 launch.json,您可以转到调试视图,选择下拉列表,然后选择 C# 选项。这应该会给您一个可以选择添加到下拉列表中的启动目标。选择后,您可以按 F5 或使用新生成的配置 启动调试

Add Dynamic C# Configuration

无 launch.json

如果您的项目中没有 launch.json,您可以在调试视图中的 显示所有自动调试配置 中添加和访问这些动态配置。

Debug with Show all automatic debug configurations

删除动态(内存中)启动配置

您可以使用命令面板 ⇧⌘P(Windows、Linux Ctrl+Shift+P调试:选择并启动调试 命令来删除生成的配置。

在下拉列表中,它列出了您的所有现有调试配置。如果您将鼠标悬停在动态配置上,右侧会出现一个可点击的垃圾桶图标。您可以选择该图标来删除动态配置。

Remove dynamic configuration

使用编辑器调试/运行按钮调试

当编辑器中打开一个 .cs 文件时,可以通过位于编辑器窗口右上角的按钮访问运行和调试选项。这些操作将使用当前文件查询项目系统并确定要启动的关联项目。

有两个选项

  • 运行与此文件关联的项目:这将使用调试适配器启动您的程序,并设置 noDebug: true
  • 调试与此文件关联的项目:这将在调试器下启动您的程序。

Editor Run or Debug

使用 launch.json 调试

如果您正在使用 C# Dev Kit,我们建议不要使用此选项。但是,如果您需要直接修改调试配置,请参阅配置 C# 调试的 launch.json

附加到进程

您可以使用命令面板 ⇧⌘P(Windows、Linux Ctrl+Shift+P并运行 调试:附加到 .NET 5+ 或 .NET Core 进程 命令来附加到 C# 进程。

Attach to a C# process

配置选项

有许多选项和设置可用于配置调试器。您可以使用 launchSettings.json、VS Code 用户设置来修改您的调试选项,或直接修改您的 launch.json

launchSettings.json

如果您有来自 Visual Studio 的 launchSettings.json,您应该可以使用 从 F5 运行从命令面板运行看到列出的配置文件。

Debugging using launchSettings.json

有关更多详细信息,请参阅配置 C# 调试

用户设置

如果您在使用 C# 调试器时希望更改设置,您可以在文件 > 首选项 > 设置⌘,(Windows、Linux Ctrl+,)下找到这些选项,并搜索这些选项。

  • csharp.debug.stopAtEntry - 如果为 true,则调试器应在目标的入口点停止。此选项默认为 false
  • csharp.debug.console - 启动控制台项目时,指示目标程序应启动到哪个控制台中。注意:此选项仅用于“dotnet”调试配置类型。
    • internalConsole [默认] - VS Code 的调试控制台。此模式允许您在一个地方查看来自调试器和目标程序的消息。有关更多详细信息,请参阅完整文档
    • integratedTerminal - VS Code 的集成终端。
    • externalTerminal - 可通过用户设置配置的外部终端。
  • csharp.debug.sourceFileMap - 将构建时路径映射到本地源位置。所有构建时路径的实例都将替换为本地源路径。
      示例
        {\"<build-path>\":\"<local-source-path>\"}
  • csharp.debug.justMyCode - 启用(默认)时,调试器仅显示并步入用户代码(“我的代码”),忽略系统代码和其他已优化或没有调试符号的代码。更多信息
  • csharp.debug.requireExactSource - 标记是否要求当前源代码与 pdb 匹配。此选项默认为 true
  • csharp.debug.enableStepFiltering - 标记是否启用跳过属性和运算符。此选项默认为 true
  • csharp.debug.logging.exceptions - 标记是否应将异常消息记录到输出窗口。此选项默认为 true
  • csharp.debug.logging.moduleLoad - 标志,用于确定是否应将模块加载事件记录到输出窗口。此选项默认为 true
  • csharp.debug.logging.programOutput - 标志,用于确定在不使用外部控制台时,是否应将程序输出记录到输出窗口。此选项默认为 true
  • csharp.debug.logging.diagnosticsLog - 用于诊断调试器问题的各种设置。
  • csharp.debug.logging.browserStdOut - 标志,用于确定是否应将启动 Web 浏览器的 stdout 文本记录到输出窗口。此选项默认为 true
  • csharp.debug.logging.elapsedTiming - 如果为 true,引擎日志将包含 adapterElapsedTimeengineElapsedTime 属性,以指示请求所花费的时间(以微秒为单位)。此选项默认为 false
  • csharp.debug.logging.threadExit - 控制在目标进程中的线程退出时是否记录消息。此选项默认为 false
  • csharp.debug.logging.processExit - 控制在目标进程退出或调试停止时是否记录消息。此选项默认为 true
  • csharp.debug.suppressJITOptimizations - 如果为 true,当优化模块(在 Release 配置中编译的 .dll)加载到目标进程中时,调试器会要求即时编译器生成禁用优化的代码。更多信息
  • csharp.debug.symbolOptions.searchPaths - 用于搜索 .pdb 文件的符号服务器 URL(例如:http://MyExampleSymbolServer)或目录(例如:/build/symbols)数组。除了模块旁边的默认位置和 pdb 最初放置的路径之外,还会搜索这些目录。
  • csharp.debug.symbolOptions.searchMicrosoftSymbolServer - 如果为 true,则将 Microsoft 符号服务器 (https://msdl.microsoft.com/download/symbols) 添加到符号搜索路径。如果未指定,此选项默认为 false
  • csharp.debug.symbolOptions.searchNuGetOrgSymbolServer - 如果为 true,则将 NuGet.org 符号服务器 (https://symbols.nuget.org/download/symbols) 添加到符号搜索路径。如果未指定,此选项默认为 false
  • csharp.debug.symbolOptions.cachePath - 应缓存从符号服务器下载的符号的目录。如果未指定,在 Windows 上,调试器默认使用 %TEMP%\\SymbolCache,在 Linux 和 macOS 上,调试器默认使用 ~/.dotnet/symbolcache
  • csharp.debug.symbolOptions.moduleFilter.mode - 控制模块过滤器运行的两种基本操作模式中的哪一种。
    • loadAllButExcluded - 为所有模块加载符号,除非该模块在 excludedModules 数组中。
    • loadOnlyIncluded - 不要尝试为任何模块加载符号,除非该模块在 includedModules 数组中,或者通过 includeSymbolsNextToModules 设置包含。
  • csharp.debug.symbolOptions.moduleFilter.excludedModules - 调试器不应为其加载符号的模块数组。支持通配符(例如:MyCompany.*.dll)。除非将 mode 设置为 loadAllButExcluded,否则将忽略此属性。
  • csharp.debug.symbolOptions.moduleFilter.includedModules - 调试器应为其加载符号的模块数组。支持通配符(例如:MyCompany.*.dll)。除非将 mode 设置为 loadOnlyIncluded,否则将忽略此属性。
  • csharp.debug.symbolOptions.moduleFilter.includeSymbolsNextToModules - 如果为 true,对于不在 includedModules 数组中的任何模块,调试器仍将检查模块本身和启动的可执行文件旁边,但不会检查符号搜索列表中的路径。此选项默认为 true。除非将 mode 设置为 loadOnlyIncluded,否则将忽略此属性。
  • csharp.debug.allowFastEvaluate - 如果为 true(默认状态),调试器将尝试通过模拟简单属性和方法的执行来进行更快的求值。
  • csharp.experimental.debug.hotReload - 如果为 true,如果目标应用程序支持热重载,调试器将启用在调试时应用更改。
  • csharp.debug.hotReloadOnSave - 如果为 true(默认状态),调试器将在保存文件时自动应用代码更改。
  • csharp.debug.hotReloadVerbosity - 控制 **C# 热重载** 输出窗口的日志详细程度。可以将其设置为 minimal (默认)、detaileddiagnostic。如果热重载开始出现意外行为,建议提高详细程度级别。

断点

C# 调试器支持各种断点,例如源代码行断点、条件断点和日志点。

断点 - 条件断点

借助表达式求值,调试器还支持条件断点。您可以将断点设置为在表达式求值为 true 时中断。

Conditional Breakpoints

断点 - 函数断点

调试器还支持函数断点。您可以通过单击“调试”窗格的“断点”部分中的 + 来设置断点以在特定函数处中断。

Function Breakpoints

断点 - 日志点

日志点(在 Visual Studio 中也称为跟踪点)允许您将输出发送到调试控制台,而无需编辑代码。它们与断点不同,因为它们不会停止应用程序的执行流程。

要添加日志点,请在代码行旁边的最左侧边距中右键单击。选择 **添加日志点** 并键入您要记录的消息。当命中日志点时,将对大括号(“{” 和 “}”)之间的任何表达式进行求值。

日志消息中还支持以下标记

标记 描述 示例输出
$FILEPOS 当前源文件位置 C:\sources\repos\Project\Program.cs:4
$FUNCTION 当前函数名 Program.<Main>$
$ADDRESS 当前指令 0x00007FFF83A54001
$TID 线程 ID 20668
$PID 进程 ID 10028
$TNAME 线程名称 <No Thread Name>
$PNAME 进程名称 C:\sources\repos\Project\bin\Debug\net7.0\console.exe
$CALLER 调用函数名 void console.dll!Program.Foo()
$CALLSTACK 调用堆栈 void console.dll!Program.Bar()
void console.dll!Program.Foo()
void console.dll!Program.<Main>$(string[] args)
[外部代码]
$TICK 刻度计数(来自 Windows GetTickCount) 28194046
$HITCOUNT 此断点被命中的次数 5

LogMessage Breakpoint

断点 - 触发的断点

触发的断点是在命中另一个断点后自动启用的断点。当诊断仅在满足某些前提条件后才会发生的代码中的故障情况时,它们非常有用。

可以通过右键单击字形边距,选择 **添加触发的断点**,然后选择启用该断点的其他断点来设置触发的断点。

在异常处停止

C# 调试器支持配置选项,用于在抛出或捕获异常时调试器停止的情况。这是通过“**运行**”视图的“**断点**”部分中的两个不同条目完成的

Exceptions settings in BREAKPOINTS Run View

请注意,在首次使用 C# 调试器调试文件夹之前,“**断点**”部分将缺少这些条目。

选中 **所有异常** 将配置调试器在抛出异常时停止。如果启用了仅我的代码(默认情况下启用),则如果异常在库代码中内部抛出并捕获,调试器将不会中断。但是,如果异常在库代码中抛出并返回到用户代码,调试器将中断。

选中 **用户未处理的异常** 将配置调试器在用户代码中抛出或穿过用户代码后,在非用户代码中捕获异常时停止。成为用户未处理的异常并不总是被调试进程中的错误 -- 可能是用户代码正在实现 API 并且预期会引发异常。在许多情况下,都存在实际问题,因此默认情况下,当异常变为用户未处理时,调试器将停止。

异常条件

这两个复选框都支持仅在选定的异常类型上中断的条件。要编辑条件,请选择铅笔图标(请参阅上图)或右键单击该条目并调用 **编辑条件**。该条件是要中断的异常类型的逗号分隔列表,如果列表以 “!” 开头,则是要忽略的异常类型的列表。

示例条件

示例条件值 结果
System.NullReferenceException 这将仅在空引用异常上中断。
System.NullReferenceException, System.InvalidOperationException 这将在空引用异常和无效操作异常上中断。
!System.Threading.Tasks.TaskCanceledException 这将中断除任务取消以外的所有异常。
!System.Threading.Tasks.TaskCanceledException, System.NotImplementedException 这将中断除任务取消和未实现之外的所有异常。

表达式求值

调试器还允许您在“**监视**”窗口以及调试控制台中求值表达式。

热重载

安装 C# Dev Kit 扩展后,调试器允许您在调试时应用 C# 代码更改。

Hot Reload displayed in the debugging toolbar

为了启用热重载,必须将 csharp.experimental.debug.hotReload 设置为 true,有关详细信息,请参阅用户设置。仅当目标调试器引擎支持应用代码更改时,才会启动热重载会话。

支持的项目和场景

C# Dev Kit 支持 “经典” 热重载体验,也称为编辑并继续。无论您是在断点处停止还是程序正在运行,您都可以在调试时应用代码更改。

截至 2023 年 11 月,某些功能(例如 MetadataUpdateHandler,它使 ASP.NET Core 应用程序能够在进行更改后自动刷新浏览器)尚不可用。也不支持在不调试的情况下应用代码更改。

运行时在 .NET 8 中添加了对在 Linux/macOS 上调试时应用更改的支持,因此在为在这些操作系统上运行的 .NET 应用应用代码更改时,需要 .NET 8+ 的运行时版本。

应用程序类型 支持使用 C# Dev Kit 的热重载 需要 .NET 8+
控制台 仅限 Linux/macOS
测试项目 仅限 Linux/macOS
类库项目 仅限 Linux/macOS
ASP.NET Core ⚠️* 目前仅支持对 .cs 文件进行更改 仅限 Linux/macOS
MAUI ❌* 即将推出 --
Unity --

有关 C# Dev Kit 当前支持的项目的详细信息,请参阅支持的项目。另请参阅 C# Dev Kit 常见问题解答,了解有关排查其他不支持的场景的更多信息。

如何应用代码更改

热重载会话开始并进行新更改后,您可以使用以下任何操作将这些更改应用到您的应用程序

操作 说明
热重载
Ctrl+Shift+Enter
应用代码更改,可从 **调试工具栏** 中获得。
保存文件
⌘S (Windows, Linux Ctrl+S)
如果 csharp.debug.hotReloadOnSave 设置为 true,则开始应用代码更改。有关详细信息,请参阅用户设置
继续 / 单步跳过 / 单步进入 / 单步跳出
F5 / F10 / F11 / ⇧F11 (Windows, Linux Shift+F11)
当在中断状态(例如,在断点处停止)时进行更改时,这些命令将自动应用这些更改。

Hot Reload demonstrated on ASP.NET

后续步骤

继续阅读以了解

  • 调试 - 了解如何在 VS Code 中使用调试器调试任何语言的项目。