在 Visual Studio 中使用跟踪点将信息记录到“输出”窗口

利用跟踪点,可以在可配置条件下将信息记录到“输出”窗口,而无需修改或停止代码。 托管语言(C#、Visual Basic、F#)和本机代码以及 JavaScript 和 Python 等语言都支持此功能。

注释

有关使用 .NET API 以编程方式将信息记录到“输出”窗口的信息,请参阅 “将消息发送到输出”窗口

让我们以示例为例

以下示例程序是一个简单的循环,其中包含一个 for 计数器变量,每次循环运行另一次迭代时都会增加一个。

示例计数器程序的屏幕截图。

以下示例程序是一个简单的循环,其中包含一个 for 计数器变量,每次循环运行另一次迭代时都会增加一个。


using System.Diagnostics;

namespace Tracepoints
{
    public class Program
    {
        public static void Main(string[] args)
        {
            int counter = 0;
            for (int i=0; i<=10; i++)
            {
                counter +=1;
            }
        }
    }
}

在源代码中设置跟踪点

可以通过在“断点设置”窗口中的“作”复选框下指定输出字符串来设置跟踪点。

  1. 若要初始化跟踪点,请先单击要在其中设置跟踪点的行号左侧的装订线。

    显示示例代码中的断点初始化的屏幕截图。

  2. 将鼠标悬停在红色圆圈上,然后单击齿轮图标。

  3. 此作将打开 “断点设置” 窗口。

    显示断点窗口的屏幕截图。

  4. 选中 “作 ”复选框。

    已选中“作框”的断点窗口的屏幕截图。

    请注意红色圆如何更改为菱形,指示已从断点切换到跟踪点。

  5. “输出窗口 ”文本框中输入要登录的消息(有关详细信息,请参阅本文后面的部分)。

    现在已设置跟踪点。 如果只想将某些信息记录到输出窗口,点击“关闭”按钮。

  6. 如果要添加用于确定是否显示邮件的条件,请选中“ 条件” 复选框。

    已选中“条件框”的断点窗口的屏幕截图。

    有三种条件选项: 条件表达式筛选器命中计数

可以通过在“断点设置”窗口中的“作”复选框下指定输出字符串来设置跟踪点。

  1. 若要初始化跟踪点,请先单击要在其中设置跟踪点的行号左侧的装订线。

    显示示例代码中的断点初始化的屏幕截图。

  2. 将鼠标悬停在红色圆圈上,然后单击齿轮图标打开 “断点设置” 窗口。

    显示断点窗口的屏幕截图。

  3. 选中 “作 ”复选框。

    已选中“作框”的断点窗口的屏幕截图。

    请注意红色圆如何更改为菱形,指示已从断点切换到跟踪点。

  4. “输出窗口 ”文本框中输入要登录的消息(有关详细信息,请参阅本文后面的部分)。

    现在已设置跟踪点。 如果只想将某些信息记录到输出窗口,点击“关闭”按钮。

  5. 如果要添加用于确定是否显示邮件的条件,请选中“ 条件” 复选框。

    已选中“条件框”的断点窗口的屏幕截图。

    有三种条件选项: 条件表达式筛选器命中计数

作菜单

此菜单允许将消息记录到“输出”窗口。 在消息框中键入要输出的字符串(无需引号)。 如果要显示变量的值,请确保将其括在大括号中。

例如,如果要在输出控制台中显示变量的值 counter ,请在消息文本框中键入 {counter}。

显示计数器输出消息的屏幕截图。

如果单击“ 关闭 ”,然后调试程序(F5),则会在“输出”窗口中看到以下输出。

显示“输出窗口中的作消息”的屏幕截图。

还可以使用特殊关键字来显示更具体的信息。 按如下所示输入关键字(在每个关键字前面使用“$”)和关键字本身的所有上限)。

关键字 显示的内容
$ADDRESS 当前指令
$CALLER 调用函数名称
$CALLSTACK 调用堆栈
$FUNCTION 当前函数名称
$PID 进程ID
$PNAME 进程名
$TID 线程 ID
$TNAME 线程名
$TICK 刻度计数(来自 Windows GetTickCount)

此菜单允许将消息记录到“输出”窗口。 在消息框中键入要输出的字符串(无需引号)。 如果要显示变量的值,请确保将其括在大括号中。

例如,如果要在输出控制台中显示变量的值 counter ,请在 {counter} 消息文本框中键入。

显示计数器输出消息的屏幕截图。

如果单击“ 关闭 ”,然后调试程序(F5),则会在“输出”窗口中看到以下输出。

显示“输出窗口中的作消息”的屏幕截图。

还可以使用特殊关键字来显示更具体的信息。 按如下所示输入关键字(在每个关键字前面使用“$”)和关键字本身的所有上限)。

关键字 显示的内容
$ADDRESS 当前指令
$CALLER 调用函数名称
$CALLSTACK 调用堆栈
$FUNCTION 当前函数名称
$PID 进程ID
$PNAME 进程名
$TID 线程 ID
$TNAME 线程名
$TICK 刻度计数(来自 Windows GetTickCount)

“条件”菜单

条件允许筛选输出消息,因此它们仅在某些情况下显示。 有三种主要条件可供你使用。

条件表达式

对于条件表达式,仅当满足某些条件时,输出消息才会显示。

对于条件表达式,可以将跟踪点设置为在某个条件为 true 或更改消息时输出消息。 例如,如果只想在循环迭代 for 期间显示计数器的值,则可以选择 “为 true ”选项,然后键入 i%2 == 0 消息文本框。

显示条件表达式为 True 的屏幕截图。

如果要在循环迭代 for 发生更改时打印计数器的值,请选择 “更改时间 ”选项并键入 i 消息文本框。

显示何时更改条件表达式的屏幕截图。

更改时 ”选项的行为对于不同的编程语言不同。

  • 对于本机代码,调试器不会将条件的第一个评估视为更改,因此不会在第一次评估中命中跟踪点。
  • 对于托管代码,调试器会在选择 “更改后 ”在第一次评估中命中跟踪点。

还可以通过将断点插入到代码的任何特定部分并选择复选框来设置跟踪点启用的条件:在“断点设置”菜单中的“断点设置”菜单中选择“仅启用”复选框。 可以从选项列表中选择任何断点。

显示当命中断点时启用的屏幕截图。

若要更全面地了解设置条件时可以使用的有效表达式,请参阅 调试器中的表达式

获取 AI 帮助

如果你有 Copilot,则可以在创建跟踪点时获得 AI 帮助。 Copilot 提供有关特定于代码 的条件断点跟踪点 的建议。

Copilot 处理条件断点建议的屏幕截图。

有关详细信息,请参阅 使用 Copilot 进行调试

对于条件表达式,仅当满足某些条件时,输出消息才会显示。

对于条件表达式,可以将跟踪点设置为在某个条件为 true 或更改消息时输出消息。 例如,如果只想在循环迭代 for 期间显示计数器的值,则可以选择 “为 true ”选项,然后键入 i%2 == 0 消息文本框。

显示条件表达式为 True 的屏幕截图。

如果要在循环迭代 for 发生更改时打印计数器的值,请选择 “更改时间 ”选项并键入 i 消息文本框。

显示何时更改条件表达式的屏幕截图。

更改时 ”选项的行为对于不同的编程语言不同。

  • 对于本机代码,调试器不会将条件的第一个评估视为更改,因此不会在第一次评估中命中跟踪点。
  • 对于托管代码,调试器会在选择 “更改后 ”在第一次评估中命中跟踪点。

若要更全面地了解设置条件时可以使用的有效表达式,请参阅 调试器中的表达式

命中计数

命中计数条件仅允许在设置跟踪点的代码行执行指定次数后发送输出。

对于命中计数,可以选择在设置跟踪点的代码行执行特定次数时输出消息。 根据要求,它可以等于或为倍数,或大于或等于指定的命中计数值。 选择最适合你的需求的选项,并在字段中键入一个整数值(例如,5),表示感兴趣的迭代。

显示条件表达式命中计数的屏幕截图。

命中计数条件仅允许在设置跟踪点的代码行执行指定次数后发送输出。

对于命中计数,可以选择在设置跟踪点的代码行执行特定次数时输出消息。 根据要求,它可以等于或为倍数,或大于或等于指定的命中计数值。 选择最适合你的需求的选项,并在字段中键入一个整数值(例如,5),表示感兴趣的迭代。

显示条件表达式命中计数的屏幕截图。

还可以通过启用复选框“ 删除断点”来删除第一次命中的断点。

显示首次命中时删除断点的屏幕截图。

过滤器

对于筛选器条件,请指定显示哪些设备、进程或线程输出。

显示条件表达式筛选器的屏幕截图。

筛选器表达式列表:

  • MachineName = “name”
  • ProcessId = 值
  • ProcessName = “name”
  • ThreadId = 值
  • ThreadName = “name”

用双引号将字符串(如名称)括起来。 可以输入值而不带引号。 可以使用 ()、(AND)、 ||!ORNOT) 和括号合并子句&

对于筛选器条件,请指定显示哪些设备、进程或线程输出。

显示条件表达式筛选器的屏幕截图。

筛选器表达式列表:

  • MachineName = “name”
  • ProcessId = value
  • ProcessName = “name”
  • ThreadId = value
  • ThreadName = “name”

用双引号将字符串(如名称)括起来。 可以输入值而不带引号。 可以使用 ()、(AND)、 ||!ORNOT) 和括号合并子句&

注意事项

虽然跟踪点旨在使调试更简洁、更流畅的体验。 在使用它们时,应注意一些注意事项。

有时,检查对象的属性或属性时,其值可能会更改。 如果在检查过程中值发生更改,则它不是由跟踪点功能本身引起的 bug。 但是,使用跟踪点检查对象不会避免这些意外的修改。

在“作”消息框中计算表达式的方式可能与当前用于开发的语言不同。 例如,若要输出一个字符串,则无需将消息包装在引号中,即使你通常使用或Debug.WriteLine()console.log()。 此外,输出表达式的大括号语法 ({ }) 也可能不同于在开发语言中输出值的约定。 (但是,仍应使用开发语言的语法编写大括号({ })中的内容。

如果尝试调试实时应用程序并查找类似的功能,请查看 Snapshot Debugger 中的日志点功能。 快照调试器是用于调查生产应用程序中问题的工具。 Logpoints 还允许将消息发送到输出窗口,而无需修改源代码,也不会影响正在运行的应用程序。 有关详细信息,请参阅 调试实时 Azure 应用程序