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