使用“任务”窗口(C#、Visual Basic、C++)

任务”窗口类似于“线程”窗口,只不过它显示有关或task_handle对象的信息System.Threading.Tasks.Task,而不是每个线程。 与线程一样,任务表示可以并发运行的异步作;但是,多个任务可能在同一线程上运行。

在托管代码中,当使用对象或 awaitasync 关键字(在 Visual Basic 中为 AwaitAsync)时,可以使用 任务 窗口。 有关托管代码中的任务的详细信息,请参阅 并行编程

在本机代码中,处理任务组并行算法异步代理轻型任务时,可以使用“任务”窗口。 有关本机代码中的任务的详细信息,请参阅 并发运行时

每当进入调试器时,都可以使用 “任务” 窗口。 可以通过单击 Windows 并单击“任务”,在“调试”菜单上访问它。 下图显示了其默认模式下的 “任务” 窗口。

任务窗口

“任务”窗口

注释

在托管代码中,具有TaskStatus.CreatedTaskStatus.WaitingForActivationTaskStatus.WaitingToRun 状态的 Task 可能不会显示在 任务 窗口中,当托管线程处于休眠或加入状态时。

任务列信息

任务” 窗口中的列显示以下信息。

列名 DESCRIPTION
标志 显示标记哪些任务,并允许标记或取消标记任务。
图标 黄色箭头 黄色箭头指示当前任务。 当前任务是当前线程上最重要的任务。

绿色箭头 绿色箭头指示当前调试器上下文(在切换到调试器中的任务之后)。

白色箭头 白色箭头指示中断任务,即调用调试器时当前任务。

暂停图标 暂停图标指示用户已冻结的任务。 可以通过在列表中右键单击任务来冻结和取消冻结任务。
ID 任务的系统提供编号。 在原生代码中,这是该任务的地址。
地位 任务的当前状态(计划、活跃、被阻塞、死锁、等待或已完成)。

状态:已计划 已计划。 计划任务是尚未运行的任务,因此还没有调用堆栈、分配的线程或相关信息。

状态处于活动状态 积极。 活动任务指的是在中断调试器之前正在执行代码的任务。

状态被阻止 阻止。 被阻止的任务是因为它正在等待一个事件发出信号、等待一个锁被释放或等待另一个任务完成而被阻止的。

状态:等待中 等待中。 使用异步/等待模式的非阻塞任务。

状态死锁 死锁。 死锁任务是一个等待中的任务,其任务的线程与另一个线程发生死锁。

将鼠标悬停在表示死锁或等待任务的状态单元格上,以查看有关该阻塞的更多信息。 警告:任务 窗口仅针对使用等待链遍历(WCT)支持的同步基元的阻塞任务报告死锁。 例如,对于使用 WCT 的 Task 死锁对象,调试器报告 Awaiting-deadlocked。 对于由并发运行时管理的死锁任务(不使用 WCT),调试器报告 正在等待。 有关 WCT 的详细信息,请参阅 等待链遍历
开始时间 任务变为活动状态的时间。
时长 任务处于活动状态的秒数。
完成时间 任务完成的时间。
位置 任务的调用堆栈中的当前位置。 将鼠标悬停在此单元格上以查看任务的整个调用堆栈。 计划任务在此列中没有值。
任务 初始方法和在创建任务时传递给任务的任何参数。
AsyncState 托管代码的任务状态。 默认情况下,此列处于隐藏状态。 若要显示此列,请打开其中一个列标题的上下文菜单。 选择 AsyncState
父母 创建此任务的任务的 ID。 如果这是空白的,则任务没有父级。 这仅适用于托管程序。
线程分配 运行任务的线程的 ID 和名称。
AppDomain 对于托管代码,任务在其中执行的应用程序域。
task_group 对于本机代码,调度任务的 task_group 对象的地址。 对于异步代理和轻型任务,此列设置为 0。
过程 任务正在运行的进程的ID。

可以通过右键单击列标题并选择所需的列,将列添加到视图中。 通过清除选择来删除列。您还可以通过左右拖动来重新排列列顺序。 下图中显示了列快捷菜单。

“任务”窗口中的快捷视图菜单

“任务”窗口中的快捷视图菜单

对任务进行排序

若要按列条件对任务进行排序,请单击列标题。 例如,通过单击 ID 列标题,可以按任务 ID 对任务进行排序:1、2、3、4、5 等。 若要反转排序顺序,请再次单击列标题。 当前排序的列和顺序由列上的箭头指示。

任务分组

可以根据列表视图中的任何列对任务进行分组。 例如,右键单击 “状态 ”列标题,然后单击“ 分组依据>[状态]”,可以对具有相同状态的所有任务进行分组。 例如,你可以快速看到等待中的任务,让你能够专注于它们被阻塞的原因。 在调试会话期间,您还可以折叠不感兴趣的组。 同样,可以按其他列进行分组。 只需单击组标题旁边的按钮即可(取消)标记组。 下图显示了分组模式下的 “任务” 窗口。

“任务”窗口中的分组模式

“任务”窗口中的分组模式

父子视图

(此视图仅适用于托管代码。通过右键单击 “状态 ”列标题,然后单击“ >级分组”,可以将任务列表更改为分层视图,其中每个子任务都是可在其父节点下显示或隐藏的子节点。

标记任务

可以通过选择任务列表项,然后从上下文菜单中选择 “标记已分配的线程”,或单击第一列中的标记图标来标记任务运行所在的线程。 如果标记多个任务,则可以对标志列进行排序,将所有已标记的任务置于顶部,以便仅关注它们。 还可以使用 “并行堆栈” 窗口仅查看已标记的任务。 这样,您可以筛选出您在调试中不感兴趣的任务。 调试会话之间不会保留标记。

冻结和解冻任务

可以通过右键单击任务列表项,然后单击“ 冻结分配的线程”来冻结任务正在运行的线程。 (如果任务已冻结,则命令为 解冻分配线程。冻结线程时,在当前断点之后单步执行代码时,该线程将不会执行。 “冻结除当前任务外的所有线程”命令会冻结所有线程,但执行任务列表项的线程除外。

下图显示了每个任务的其他菜单项。

“任务”窗口中的快捷线程菜单

“任务”窗口中的快捷线程菜单

切换活动任务或框架

“切换到任务”命令使当前任务成为活动任务。 “切换到帧”命令将所选堆栈帧设置为活动堆栈帧。 调试器上下文切换到当前任务或所选堆栈帧。