在“并行堆栈”窗口中查看线程和任务(C#、Visual Basic、C++)
并行堆栈 窗口可用于调试多线程应用程序。 它有多个视图:
线程视图 显示应用中所有线程的调用堆栈信息。 可以在这些线程上的线程和堆栈帧之间导航。
任务视图显示以任务为中心的调用堆栈信息。
- 在托管代码中,任务 视图显示 System.Threading.Tasks.Task 对象的调用堆栈。
- 在本机代码中,任务 视图显示 任务组的调用堆栈、并行算法、异步代理,以及 轻量级任务。
方法视图 将调用堆栈围绕所选方法进行旋转。
使用“并行堆栈”窗口
若要打开 并行堆栈 窗口,必须位于调试会话中。 选择“调试”>“窗口”>“并行堆栈”。
工具栏控件
并行堆栈 窗口具有以下工具栏控件:
图标 | 控件 | 描述 |
---|---|---|
![]() |
线程/任务 组合框 | 在线程的调用堆栈和任务的调用堆栈之间切换视图。 有关详细信息,请参阅 任务视图 和 线程视图。 |
![]() |
仅显示已标记项 | 仅显示其他调试器窗口中标记的线程的调用堆栈,例如 GPU 线程 窗口和 并行监视 窗口。 |
![]() |
切换“方法视图” | 在调用堆栈视图和方法视图之间切换。 有关详细信息,请参阅 方法视图。 |
![]() |
自动滚动到当前堆栈帧 | 自动滚动图形,使当前堆栈帧在视图中。 当从其他窗口更改当前堆栈帧或在大型图形中命中新的断点时,此功能非常有用。 |
![]() |
切换缩放控件 | 显示或隐藏窗口左侧的缩放控件。 无论缩放控件的可见性如何,也可以通过按 |
图标 | 控件 | 描述 |
---|---|---|
![]() |
线程/任务 组合框 | 在调用线程堆栈视图和调用任务堆栈视图之间切换。 有关详细信息,请参阅 任务视图 和 线程视图。 |
![]() |
筛选器 控件 | 仅显示你感兴趣的特定线程集的调用堆栈。 |
![]() |
仅显示已标记项 | 仅显示其他调试器窗口中标记的线程的调用堆栈,例如 GPU 线程 窗口和 并行监视 窗口。 |
![]() |
切换“方法视图” | 在调用堆栈视图和方法视图之间切换。 有关详细信息,请参阅 方法视图。 |
![]() |
自动滚动到当前堆栈帧 | 自动滚动图形,使当前堆栈帧在视图中。 当从其他窗口更改当前堆栈帧或在大型图形中命中新的断点时,此功能非常有用。 |
![]() |
切换缩放控件 | 显示或隐藏窗口左侧的缩放控件。 无论缩放控件的可见性如何,也可以通过按 |
![]() |
搜索控件 | 借助此功能,可以轻松搜索堆栈帧,然后使用箭头在这些结果之间导航。 |
![]() |
保存控件 | 使你能够将并行堆栈窗口中的内容保存/导出为图像。 |
![]() |
显示外部代码控件 | 使用此功能,可以从外部代码/库显示/隐藏堆栈。 |
堆栈帧图标
以下图标提供有关所有视图中的活动和当前堆栈帧的信息:
图标 | 描述 |
---|---|
![]() |
指示当前线程的当前位置(活动堆栈帧)。 |
![]() |
指示非当前线程的当前位置(活动堆栈帧)。 |
![]() |
指示当前堆栈帧(当前调试器上下文)。 无论方法名称出现在哪里,方法名称都是粗体。 |
图标 | 描述 |
---|---|
![]() |
指示当前线程的当前位置(活动堆栈帧)。 |
![]() |
指示非当前线程的当前位置(活动堆栈帧)。 |
![]() |
指示当前堆栈帧(当前调试器上下文)。 无论方法名称出现在哪里,方法名称都是粗体。 |
![]() |
指示当前堆栈帧具有严重状态警告,例如死锁。 |
状态排除 ![]() |
指示死锁节点。 |
![]() |
指示当前堆栈帧具有其他信息,例如“正在等待”、“正在等待锁定”、“拥有者”等。 |
![]() |
指示当前任务处于阻塞/等待中状态等。 |
![]() |
指示当前正在运行的任务。 |
上下文菜单项
右键单击 线程 视图或 任务 视图中的方法时,可以使用以下快捷菜单项。 最后六项与“调用堆栈”窗口中的相同。
菜单项 | 描述 |
---|---|
标记 | 标记选定项。 |
取消标记 | 取消标记选定项。 |
冻结 | 冻结所选项目。 |
解冻 | 解冻选定项。 |
切换到帧 | 与 调用堆栈 窗口中的相应菜单命令相同。 但是,在 并行堆栈 窗口中,一种方法可能位于多个帧中。 可以在此项目的子菜单中选择所需的帧。 如果其中一个堆栈帧位于当前线程上,则默认情况下在子菜单中选择该帧。 |
转到任务 或 转到线程 | 切换到“任务”或“线程”视图,并突出显示相同的堆栈帧。 |
转到源代码 | 转到源代码窗口中的相应位置。 |
转到反汇编 | 转到“反汇编”窗口中的相应位置。 |
显示外部代码 | 显示或隐藏外部代码。 |
十六进制显示 | 在十进制和十六进制显示之间切换。 |
在源 中显示线程 | 标记线程在源代码窗口中的位置。 |
符号加载信息 | 打开“符号加载信息”对话框。 |
符号设置 | 打开“符号设置” 对话框。 |
菜单项 | 描述 |
---|---|
复制 | 复制选定项。 |
选择下面的所有帧 | 选择所选堆栈下的所有帧。 |
标记 | 标记选定项。 |
取消标记 | 取消标记选定项。 |
冻结 | 冻结所选项目。 |
解冻 | 解冻选定项。 |
切换到帧 | 与 调用堆栈 窗口中的相应菜单命令相同。 但是,在 并行堆栈 窗口中,一种方法可能位于多个帧中。 可以在此项目的子菜单中选择所需的帧。 如果其中一个堆栈帧位于当前线程上,则默认情况下在子菜单中选择该帧。 |
转到任务 或 转到线程 | 切换到“任务”或“线程”视图,并突出显示相同的堆栈帧。 |
转到源代码 | 转到源代码窗口中的相应位置。 |
转到反汇编 | 转到“反汇编”窗口中的相应位置。 |
显示外部代码 | 显示或隐藏外部代码。 |
十六进制显示 | 在十进制和十六进制显示之间切换。 |
在源 中显示线程 | 标记线程在源代码窗口中的位置。 |
符号加载信息 | 打开“符号加载信息”对话框。 |
符号设置 | 打开“符号设置” 对话框。 |
线程视图
在 线程 视图中,当前线程的堆栈帧和调用路径以蓝色突出显示。 线程的当前位置由黄色箭头显示。
若要更改当前堆栈帧,请双击其他方法。 这也可能会切换当前线程,具体取决于所选方法是当前线程的一部分还是另一个线程。
当 线程 视图图太大而无法容纳到窗口中时,窗口中会显示 鸟眼视图 控件。 可以移动控件中的框架以导航到图形的不同部分。
下图演示的是一个执行从主代码到托管代码再到本机代码的代码转换的线程。 当前方法中有六个线程。 两个线程继续执行 Thread.Sleep,两个线程继续执行 Console.WriteLine,而当前线程继续执行 SyncTextWriter.WriteLine。
下表介绍了 线程 视图的主要功能:
标注 | 元素名称 | 描述 |
---|---|---|
1 | 调用堆栈段或节点 | 包含一个或多个线程的一系列方法。 如果帧没有与之连接的箭头线,则框架将显示线程的整个调用路径。 |
2 | 蓝色突出显示 | 指示当前线程的调用路径。 |
3 | 箭头线 | 连接节点以构成线程的整个调用路径。 |
4 | 节点标头 | 显示节点的进程和线程数。 |
5 | 方法 | 表示同一方法中的一个或多个堆栈帧。 |
6 | 方法上的工具提示 | 将鼠标悬停在方法上时显示。 在 线程 视图中,工具提示显示与“线程”窗口类似的表中的所有线程。 |
下图展示了从托管代码到本机代码转换过程中的主线程。 当前方法中有五个线程。 四个线程继续在 S.C 方法上下文中执行,而一个工作线程在托管到本机代码转换中继续执行,并在工作线程上设置名称。
下表介绍了 线程 视图的主要功能:
标注 | 元素名称 | 描述 |
---|---|---|
1 | 调用堆栈段或节点 | 包含一个或多个线程的一系列方法。 如果帧没有与之连接的箭头线,则框架将显示线程的整个调用路径。 |
2 | 蓝色突出显示 | 指示当前线程的调用路径。 |
3 | 箭头线 | 连接节点以构成线程的整个调用路径。 |
4 | 节点标头 | 显示节点的进程/线程数、线程名称和线程 ID。 |
5 | 方法 | 表示同一方法中的一个或多个堆栈帧。 |
6 | 方法上的工具提示 | 将鼠标悬停在方法上时显示。 在 线程 视图中,工具提示显示与“线程”窗口类似的表中的所有线程。 |
7 | 线程说明 | AI 生成的话题说明。 从 Visual Studio 2022 版本 17.13 预览版 1 开始,安装并激活 Copilot 时,将显示此说明。 |
任务视图
如果你的应用使用 System.Threading.Tasks.Task 对象(托管代码)或 task_handle
对象(本机代码)来表达并行度,则可以使用 任务 视图。 任务 视图显示的是任务的调用堆栈,而不是线程的调用堆栈。
在“任务”视图中:
- 不显示未运行任务的线程的调用堆栈。
- 身为运行中任务的线程,其调用堆栈的首尾将被隐藏,以显示与任务关系最密切的帧。
- 当多个任务位于一个线程上时,这些任务的调用堆栈将显示在单独的节点中。
若要查看整个调用堆栈,请右键单击堆栈帧并选择“转到线程”以切换回“线程”视图。
下图显示了顶部 线程 视图,以及底部相应的 任务 视图。
将鼠标悬停在方法上以显示包含其他信息的工具提示。 在 任务 视图中,工具提示显示表中的所有任务,类似于 任务 窗口。
以下图片显示了顶部 线程 视图中某方法的工具提示,以及底部对应的 任务 视图中的工具提示。
方法视图
在“线程”视图或“任务”视图中,可以通过选择工具栏上的“切换方法视图”图标,以当前方法为中心显示图形。 “方法视图”非常清晰地显示了调用当前方法或被当前方法调用的所有线程上的所有方法。 下图显示了左侧 线程 视图和右侧 方法视图 中相同信息的外观。
如果切换到新的堆栈帧,则可以将该方法设为当前方法,方法视图 将显示新方法的所有调用方和被调用方。 这可能会导致某些线程从视图中显示或消失,具体取决于该方法是否出现在其调用堆栈上。 若要返回到调用堆栈视图,请再次选择 方法视图 工具栏图标。
使用并行堆栈调试线程和任务视频教程
这些视频教程演示如何使用 Visual Studio 2022 中并行堆栈窗口的“线程和任务”视图来调试多线程应用程序。
- 使用“并行堆栈”窗口调试任务
- 使用“并行堆栈”窗口 调试线程