在 Visual Studio 调试器中查看线程(C#、Visual Basic、C++)

Visual Studio 调试器中的“线程”窗口允许检查和处理正在调试的应用程序中的线程。 该窗口提供对代码中的线程进行分组、排序、标记、冻结、解冻和搜索以及显示调用堆栈的功能。

线程 窗口仅在 Visual Studio 调试器运行时可用。 在调试会话期间,可以通过选择 调试>Windows>线程来打开窗口。

本文介绍如何使用 C#、Visual Basic 或 C++ 程序的 线程 窗口。 如果要查找有关如何使用 线程 窗口的分步指南,请参阅 演练:使用“线程”窗口进行调试

浏览“线程”窗口表

线程 窗口显示一个表,其中每行对应于应用程序中的单独线程。 在默认视图中,表显示应用程序中的所有线程。 可以将表设置配置为仅显示感兴趣的线程。 该表提供了多个列来详细描述线程。 可以调整列的位置并隐藏不必要的列。

下表描述了 线程 窗口表的所有可用列,并指示该列在默认视图中是可见还是隐藏。 列按照它们在表中的默认位置从左到右列出。

违约 描述
标记 可见,未标记 此列中的红色标记表示线程被标记为需要特别注意。 选择该标记(图标颜色更改为红色)可标记或取消标记(图标更改为标记轮廓)线程。 彩色标志图标有助于区分标记线程与表中的其他线程。 有关详细信息,请参阅标记和取消标记线程
当前线程 可见,未标记 此列中的黄色箭头图标指示调试器中运行的应用程序中的当前线程。 此列中的箭头轮廓图标指示非当前线程的当前调试器上下文。
ID 可见 为每个线程提供标识号。
托管 ID 可见 显示托管线程的托管标识号。
类别 可见 将线程类别指示为用户界面线程、远程过程调用处理程序或工作线程。 特殊类别标识应用程序的主线程。
名称 可见 按其名称标识每个线程,或者如果线程没有指定名称,则 <无名称>。 当线程不再存在时,线程具有标签 [Thread Destroyed]。
位置 可见 显示线程在应用程序调用堆栈中运行的位置。 选择下拉箭头以查看线程的完整调用堆栈。 当线程不再存在时,该位置标记为 <不可用>。
优先级 隐藏 显示系统分配给每个线程的优先级或优先顺序。
关联掩码 隐藏 显示每个线程的处理器关联掩码。 在多处理器系统中,关联掩码确定线程可在其上运行的处理器。
暂停计数 隐藏 提供挂起项计数。 此计数确定线程是否可以运行。 有关详细信息,请参阅 冻结和解冻线程
进程名称 隐藏 显示每个线程所属的进程。 调试许多进程时,此列中的数据非常有用。
进程标识符 隐藏 显示每个线程所属的进程 ID。
传输限定符 隐藏 唯一标识调试程序连接到的计算机。

显示和隐藏表列

在“线程”窗口工具栏中,“列”下拉菜单显示可用列的列表。 展开下拉列表并选择列名称以切换表中的可见性。 列表中用复选标记指示可见列。

标记要特别关注的线程

使用标志图标标记线程以供特别注意。 标记的线程由 线程 窗口表中的红色标志图标指示。 有关详细信息,请参阅标记和取消标记线程

仅显示已标记的线程

可以筛选 线程 窗口,仅显示已标记的线程。 在 线程 窗口工具栏中,选择 仅显示已标记的线程(双旗帜图标)。 可以使用 Ctrl + 9 键盘快捷方式。 仅当存在已标记的线程时,此操作才可用。

冻结和解冻线程

冻结线程时,即使资源可用,系统也不会开始执行线程。

在本机代码中,可以通过调用 Windows 函数 SuspendThreadResumeThread来暂停或恢复线程。 还可以 CWinThread::SuspendThreadCWinThread::ResumeThread调用 MFC 函数。 如果你调用 SuspendThreadResumeThread 函数,则“线程”窗口显示中的“挂起项计数”更改。 如果冻结或解冻本地线程,暂停计数不会更改。 除非线程解冻且挂起项计数为零,否则线程无法在本机代码中执行。

在托管代码中,冻结或解冻线程时,挂起项计数会更改。 如果在托管代码中冻结一个线程,该线程的挂起计数将为 1。 在本机代码中冻结线程时,其挂起项计数为 0,除非使用 SuspendThread 调用。

注意

在调试从本机代码到托管代码的调用时,托管代码在与调用本机代码相同的物理线程中运行。 暂停或冻结本机线程也会冻结托管代码。

更改所选线程的执行方式

可以冻结或解冻一个或多个线程的执行。 在 线程 窗口中,选择要更新执行状态的线程。 在 线程 窗口工具栏中,选择 冻结线程(暂停播放图标)或 解冻线程(绿色播放图标)。 该操作仅适用于当前选定的线程。 每个线程的右键单击上下文菜单中也提供了冻结和解冻操作。

更改当前线程

线程 窗口表中的黄色箭头图标指示当前线程(和执行指针的位置)。 原始当前线程标记也保持不变(用箭头轮廓图标显示)。

线程 窗口表中的黄色箭头图标指示当前线程(和执行指针的位置)。 带有卷尾的绿色箭头图标表示非当前线程具有当前调试程序上下文。

切换到另一个线程

可通过两种方式在调试器中切换当前线程。 双击 线程 窗口表中的任何线程使其成为当前线程。 还可以右键单击线程并选择 切换到线程

将分组和排序应用于线程

可以使用与可用列相同的条件,将 线程 窗口表中的线程分组。 无论相应的列在当前视图中是否可见,所有条件始终可用于分组。 您只能为该表选择一个分组。

对线程进行分组时,每个组的表中会显示一个标题。 标题包括组说明以及组中的成员数。 如果按“名称”分组,则可能会看到标题为“工作线程”或“未标记线程”等的分组。 展开/折叠箭头图标显示在每个组标题旁边。

应用分组条件后,“线程”窗口表的视图将更新,以在各自标题下显示每个组的成员线程。 使用组的展开/折叠箭头图标显示或隐藏当前视图中的成员。

还可以将单个排序条件应用于 线程 窗口表中的线程。 分组优先于排序。 例如,可以通过 类别 对线程进行分组,然后在每个 类别中按 ID 对其进行排序。

对表中的线程进行分组

线程 窗口工具栏中,按 下拉列表展开 组,然后选择用于对线程进行分组的条件。 还可以通过在“分组依据”下拉列表中选择“无”来删除已应用的分组

对表中的线程进行排序

通过选择表格顶部的列标题(例如 名称ID),在 线程 窗口中应用对线程的排序。

选择列标题时,线程 窗口表的视图会更新,以显示按所选列中的值排序的线程。 所选列还显示向上/向下箭头图标。 向上箭头图标表示按升序对所选列排序。 向下箭头图标表示按所选列降序排序。 选择列标题以更改排序顺序。

对组中的线程进行排序

若要在“线程”窗口中对组中的线程进行排序,请先使用 分组依据 下拉列表来应用分组条件。 然后,选择列标题以按所选列中的值对分组线程进行排序。

展开或折叠所有组

可通过快速方式显示或隐藏当前视图中的所有分组。 在 线程 窗口工具栏中,选择 展开组(带加号的双框图标)或 折叠组(带减号的双框图标)。

搜索帖子

可以在 线程 窗口表中搜索线程,并在任何可见表列中查找特定内容。 执行搜索时,Visual Studio 将显示具有与搜索字符串匹配的列数据的线程行。 搜索还会扫描 位置 列中调用堆栈顶部显示的线程位置。

在线程中搜索特定内容

可通过多种方式搜索线程来查找特定内容。 在 线程 窗口的工具栏中,在 搜索 框中输入要查找的字符串,然后按下 “Enter”键。 可以在搜索字符串中指定字母、数字和特殊字符,例如 <。 搜索完成后,线程 窗口将更新表以显示具有匹配结果的线程。 Visual Studio 突出显示与搜索字符串匹配的特定实例。 若要返回到常规线程视图,请选择 搜索 框旁边的 X 图标。

还可以搜索以前查找的字符串。 使用 搜索 下拉列表框并选择以前的搜索字符串。

搜索完整调用堆栈

默认情况下,不会搜索完整的调用堆栈。 Visual Studio 仅在“线程”窗口表中可见的线程中搜索匹配项

可以通过在“线程”窗口工具栏中选择“在搜索中包含调用堆栈”(列表项图标)来包含完整调用堆栈。 启用该选项后,列表项图标具有边框。

显示调用堆栈并在帧之间切换

在多线程程序中,每个线程都有自己的调用堆栈。 线程 窗口提供了一种查看这些堆栈的便捷方法。

提示

对于每个线程的调用堆栈的可视表示形式,请使用 并行堆栈 窗口。

查看线程的调用堆栈

线程 窗口表中,找到要检查完整调用堆栈的线程。 在 位置 列中,选择线程位置左侧的展开/折叠箭头。 该位置展开以显示线程的完整调用堆栈。 再次选择箭头以仅显示位置。

查看或折叠所有调用堆栈

可以控制 线程 窗口是否始终显示表中所有线程的完整调用堆栈。 在 线程 窗口工具栏中,选择 展开调用堆栈(带加号的框图标)或 折叠调用堆栈(带减号的框图标)。