演练:调试多线程应用程序

Visual Studio 2012 提供了改进的**“线程”**窗口和其他用户界面改善,可以简化多线程应用程序的调试。 本演练只需几分钟即可完成,但完成后您将熟悉用于调试多线程应用程序的一些新增界面功能。

若要开始本演练,您需要创建一个多线程应用程序项目。 请按照下面列出的步骤创建该项目。

创建演练项目

  1. 在**“文件”菜单上选择“新建”,再单击“项目”**。

    此时将出现**“新建项目”**对话框。

  2. 在**“项目类型”框中单击所选的语言:“Visual Basic”“Visual C#”“Visual C++”**。

  3. 在**“模板”框中选择“控制台应用程序”“CLR 控制台应用程序”**。

  4. 在**“名称”**框中键入名称 MyThreadWalkthroughApp。

  5. 单击**“确定”**。

    新的控制台项目随即显示。 创建该项目后,将显示源文件。 根据所选的语言,源文件的名称可能是 Module1.vb、Program.cs 或 MyThreadWalkthroughApp.cpp

  6. 删除源文件中出现的代码,并将其替换为启动时创建线程并传递数据主题的“创建线程”一节中出现的代码示例。

  7. 在**“文件”菜单上,单击“全部保存”**。

开始演练

  • 在源窗口中查找以下代码:

    Thread.Sleep(3000) 
    Console.WriteLine(
    
Thread.Sleep(3000);
Console.WriteLine();
Thread::Sleep(3000);
Console.WriteLine();

开始调试

  1. 右击 Console.WriteLine 语句,指向**“断点”,再单击“插入断点”**。

    在源窗口左侧的滚动条槽中将显示一个红色球。 这表示现在已在该位置设置了一个断点。

  2. 在**“调试”菜单上,单击“启动调试”**。

    调试开始,您的控制台应用程序开始运行,随后在断点处停止。

  3. 如果此时控制台应用程序窗口具有焦点,请在 Visual Studio 窗口中单击以使焦点返回到 Visual Studio。

  4. 在源窗口中,找到包含以下代码的行:

    Thread.Sleep(5000) 
    
Thread.Sleep(3000);
Thread::Sleep(3000);

发现线程标记

  1. 在**“线程”窗口中右击,然后单击“在源中显示线程”**。

  2. 查看窗口左侧的滚动条槽。 在这条槽线上,您将看到一个类似于两根细线的图标。 一根线是红色的,另一根是蓝色的。 线程标记指示线程在此位置停止。 线程有可能在此位置停止。

  3. 将指针悬停在线程标记上。 数据提示随即显示。 数据提示将告诉您每个已停止线程的名称和线程 ID 号。 在此情况下,只有一个线程,其名称可能是 <noname>。

  4. 右击线程标记。 请注意快捷菜单上的选项。

此图标是一个线程标记:

线程标记

标记线程和取消标记线程

在 Visual Studio 2008 中,可以标记要格外关注的线程。 标记线程是一种跟踪重要线程并忽略您不关心的线程的好方法。

标记线程

  1. 在**“视图”菜单上指向“工具栏”**。

    请确保选中**“调试位置”**工具栏。

  2. 转到**“调试位置”工具栏,然后单击“线程”**列表。

    备注

    可以通过三个突出显示的列表“进程”“线程”“堆栈帧”来识别此工具栏。

  3. 请注意列表中显示的线程数目。

  4. 返回源窗口,再次右击**“线程”**标记。

  5. 在快捷菜单上指向**“标记”**,再单击线程名称和 ID 号。

  6. 返回**“调试位置”工具栏,再次单击“线程”**列表。

    现在只有标记的线程显示在该列表中。 标记按钮位于**“线程”**列表的右侧。 之前该按钮上的标记图标灰显, 现在显示为纯鲜红色。

  7. 将指针悬停在标记图标上。

    弹出消息随即显示。 此弹出消息告诉您**“线程”列表所处的模式:“仅显示已作标记的线程”**。

  8. 单击标记按钮切换回**“显示所有线程”**模式。

  9. 再次单击**“线程”**列表,并确认此时是否可以再次看到所有线程。

  10. 单击标记按钮切换回**“仅显示已作标记的线程”**模式。

  11. 在**“调试”菜单上指向“窗口”,再单击“线程”**。

    **“线程”**窗口随即显示。 其中有一个线程上附加了突出显示的标记图标。

  12. 在源窗口中再次右击线程标记。

    请注意此时快捷菜单上提供的选项。 这时显示的是**“取消标记”而非“标记”。 请不要单击“取消标记”**。

  13. 转到有关如何取消标记线程的下一个过程。

取消标记线程

  1. 在**“线程”**窗口中右击与标记的线程相对应的行。

    一个快捷菜单随即显示。 其中包括**“取消标记”“全部取消标记”**选项。

  2. 若要取消标记线程,请单击**“取消标记”**。

  3. 单击红色的标记图标。

  4. 再次查看**“调试位置”工具栏。 标记按钮再次灰显。 这是因为您已取消标记唯一的已标记线程。 由于没有已标记的线程,工具栏将返回“显示所有线程”模式。 单击“线程”**列表,并确认是否可以看到所有线程。

  5. 返回到**“线程”**窗口并检查信息列。

    在每一列顶部,大多数按钮都带有相应的标题,用于标识该列。 不过,左侧的第一列上没有标题, 而是显示了一个图标,即标记的边框。 您将注意到该线程列表的每一行中有相同的边框。 该边框意味着该线程已取消标记。

  6. 单击两个线程(即从列表底部起的第二和第三个线程)的标记边框。

    标记图标变为纯红色,而非空心边框。

  7. 单击该标记列顶部的按钮。

    单击该按钮时,线程列表的顺序将会改变。 此时,线程列表的排序形式为标记的线程位于顶部。

  8. 再次单击该标记列顶部的按钮。

    排序顺序再次改变。

有关“线程”窗口的更多信息

了解有关“线程”窗口的更多信息

  1. 在**“线程”窗口中检查从左侧起的第三列。 此列顶部的按钮上显示“ID”**。

  2. 单击**“ID”**。

    此时,线程列表按照线程 ID 号排序。

  3. 右击列表中的任意线程。 在快捷菜单上,单击**“十六进制显示”**。

    线程 ID 号的格式将会改变。

  4. 将鼠标指针悬停在列表中的任意线程上。

    经过短暂的延迟后,将会出现数据提示。 其中显示线程的部分调用堆栈。

  5. 查看从左侧起的第四列,该列标记为**“类别”**。 线程按类别分类。

    进程中创建的第一个线程称为主线程。 请在线程列表中找到它。

  6. 右击主线程,再单击**“切换到线程”**。

    一个警告对话框随即显示。 它通知您 Visual Studio 无法显示主线程的源代码。

    单击**“确定”**。

  7. 查看**“调用堆栈”窗口与“调试位置”**工具栏。

    **“调用堆栈”**窗口的内容已经更改。

切换活动线程

切换线程

  1. 在**“线程”窗口中检查从左侧起的第二列。 此列顶部的按钮上没有文本或图标。 此列为“活动线程”**列。

  2. 查看**“活动线程”**列,将会看到一个线程带有黄色箭头。 这是“活动线程指示符”。

  3. 记下活动线程指示符所在位置的线程 ID 号。 您可以将活动线程指示符移到另一个线程,但在完成操作后必须将其移回原位。

  4. 右击另一个线程,再单击**“切换到线程”**。

  5. 查看源窗口中的**“调用堆栈”**窗口。 其内容已经更改。

  6. 查看**“调试位置”**工具栏。 其中的活动线程也已更改。

  7. 转到**“调试位置”工具栏。 单击“线程”**框并从下拉列表中选择其他线程。

  8. 查看**“线程”**窗口。 活动线程指示符已经更改。

  9. 在源窗口中右击线程标记。 在快捷菜单上指向**“切换到”**,再单击线程名称/ID 号。

    您现在已经了解了更改活动线程的三种方式:使用**“线程”窗口、“调试位置”工具栏中的“线程”**框以及源窗口中的线程指示符。

    使用线程指示符只能切换到在特定位置停止的线程。 而使用**“线程”窗口和“调试位置”**工具栏可以切换到任何线程。

线程执行的冻结和解冻

冻结和解冻线程

  1. 在**“线程”窗口中右击任一线程,再单击“冻结”**。

  2. 查看活动线程列。 此时该列中出现一对竖线。 这两条蓝色竖线表示该线程已冻结。

  3. 查看**“挂起”**列。 此时线程的挂起计数是 1。

  4. 右击冻结的线程,再单击**“解冻”**。

    活动线程列与**“挂起”**列发生更改。

请参见

任务

如何:在调试时切换到另一个线程

其他资源

在 Visual Studio 中调试多线程应用程序