65.9K
CodeProject 正在变化。 阅读更多。
Home

Visual Studio 2015 中的断点配置和新的错误列表

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.62/5 (9投票s)

2016年5月25日

CPOL

11分钟阅读

viewsIcon

20317

本文介绍了 Visual Studio 2015 在调试方面所做的改进。

引言

Visual Studio 始终是用于代码调试的优秀 IDE。它提供了许多用于调试和配置代码的功能。作为开发人员,我们总是花费大量时间运行和调试代码,因此调试功能的改进可以极大地提高我们的生产力。本文介绍了 Visual Studio 2015 在调试方面所做的改进。以下是本文将涵盖的一些主要功能:

  • 断点配置改进
  • 全新改进的错误列表
  • 对 LINQ 和 Lambda 表达式的工具窗口支持
  • 在代码编辑器中显示执行时间的新 PerfTips
  • 新的诊断工具窗口

学习 Visual Studio 2015 系列

断点配置改进

Visual Studio 的早期版本已经提供了断点配置功能,因此这对开发人员来说并不陌生。Visual Studio 2015 中唯一的新功能是用户体验和使用配置的便捷性。断点配置现在更易于使用和访问。Visual Studio 2015 引入了一个新的内联工具栏。通过此工具栏,您可以轻松打开断点配置设置或启用/禁用断点。其次,Visual Studio 2015 中断点配置的上下文菜单得到了简化。上下文菜单中的一些选项已移至断点配置设置窗口。设置窗口现在以“窥视”窗口的形式出现,因此您可以轻松检查和更改设置,因为不再有模式窗口。整个断点配置现在分为两个部分:操作和条件。让我们通过实际实现来详细了解该主题。我正在使用 Visual Studio 2015 企业版来撰写本文,并在我的 Visual Studio 中添加了一个名为 VS2015ConsoleApplication 的控制台应用程序。假设我们有一个 MyProduct 类,其中包含产品作为实体特定的基本操作,例如获取产品、返回产品列表,如下所示。

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using System.Threading.Tasks;
   6:  
   7: namespace VS2015ConsoleApplication
   8: {
   9:     public class MyProducts :IProducts
  10:     {
  11:         List<Product> _allProduct = new List<Product>();
  12:         public MyProducts()
  13:         {
  14:             _allProduct.Add(new Product {ProductCode="0001",ProductName="IPhone",ProductPrice="60000",ProductType="Phone",ProductDescription="Apple IPhone" } );
  15:             _allProduct.Add(new Product { ProductCode = "0002", ProductName = "Canvas", ProductPrice = "20000", ProductType = "Phone", ProductDescription = "Micromax phone" });
  16:             _allProduct.Add(new Product { ProductCode = "0003", ProductName = "IPad", ProductPrice = "30000", ProductType = "Tab", ProductDescription = "Apple IPad" });
  17:             _allProduct.Add(new Product { ProductCode = "0004", ProductName = "Nexus", ProductPrice = "30000", ProductType = "Phone", ProductDescription = "Google Phone" });
  18:             _allProduct.Add(new Product { ProductCode = "0005", ProductName = "S6", ProductPrice = "40000", ProductType = "Phone", ProductDescription = "Samsung phone" });
  19:  
  20:         }
  21:  
  22:         /// <summary>
  23:         /// FetchProduct having price greater that 3000
  24:         /// </summary>
  25:         /// <returns></returns>
  26:         public List<Product> FetchProduct() => (from p in _allProduct where Convert.ToInt32(p.ProductPrice) > 30000 select p).ToList();
  27:  
  28:         /// <summary>
  29:         /// FetchProduct
  30:         /// </summary>
  31:         /// <param name="pCode"></param>
  32:         /// <returns></returns>
  33:         public Product FetchProduct(string pCode)
  34:         {
  35:             return _allProduct.Find(p => p.ProductCode == pCode);
  36:         }
  37:  
  38:         /// <summary>
  39:         /// FetchProduct with productCode and productName
  40:         /// </summary>
  41:         /// <param name="productCode"></param>
  42:         /// <param name="productName"></param>
  43:         /// <returns></returns>
  44:         public Product FetchProduct(string productCode, string productName)
  45:         {
  46:             return _allProduct.Find(p => p.ProductCode == productCode && p.ProductName==productName);
  47:         }
  48:  
  49:         public List<Product> GetProductList()
  50:         {
  51:             return _allProduct;
  52:         }
  53:     }
  54: }

其中 IProducts 是一个简单的接口。

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using System.Threading.Tasks;
   6:  
   7: namespace VS2015ConsoleApplication
   8: {
   9:     interface IProducts
  10:     {
  11:         Product FetchProduct(string productCode);
  12:         Product FetchProduct(string productCode,string productName);
  13:         List<Product> GetProductList();
  14:     }
  15: }

在下面的 Program 类中,我们只是获取所有产品并为名为 ProductCodeWithPrice 的新实体创建一个新的产品列表,其中我们只列出产品的产品代码和价格。

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using System.Threading.Tasks;
   6:  
   7: namespace VS2015ConsoleApplication
   8: {
   9:     public class ProductCodeWithPrice
  10:     {
  11:         public string ProductCode { get; set; }
  12:         public string ProductPrice { get; set; }
  13:  
  14:     }
  15:     class Program
  16:     {
  17:         static void Main()
  18:         {
  19:             var myProducts = new MyProducts();
  20:             var products = new List<ProductCodeWithPrice>();
  21:             var allProducts = myProducts.GetProductList();
  22:             foreach (var product in allProducts )
  23:             {
  24:                 ProductCodeWithPrice prod = new ProductCodeWithPrice();
  25:                 prod.ProductCode = product.ProductCode;
  26:                 prod.ProductPrice = product.ProductPrice;
  27:                 products.Add(prod);
  28:             }
  29:             Console.ReadLine();
  30:         }
  31:     }
  32: }

现在,假设我们正在调试代码,同时创建了一个新的产品列表,并且我们希望在 foreach 循环中创建新的 ProductCodePrice 实例之后放置一个断点。

当在第 27 行设置断点时,请注意新的内联工具栏。从这里我可以打开设置或启用和禁用断点。当我们右键单击断点以打开上下文菜单时,我们看到一个新的简化上下文菜单,其中大部分以前存在的选项现在已移至设置选项。

让我们再次检查内联工具栏。我们选择“设置”选项。请注意,设置现在以“窥视”窗口的形式出现,而不是模式对话框窗口。这有助于开发人员在调试时轻松修改设置。

条件

让我们尝试探索条件是如何工作的。当我们设置断点并打开设置窗口时,它会显示“条件”和“操作”选项,并提及断点的位置以及文件名、行号和字符位置等详细信息。单击条件复选框会显示其他一些有关如何配置条件的选项。

默认是“条件表达式”,但还有另外两个选项,即“命中计数”和“筛选器”。当需要在循环中的特定迭代处暂停执行时,可以使用“命中计数”选项。

第二个下拉列表用于验证条件。在这种情况下,我们在每次迭代中创建 prod 对象后放置了一个断点。

请注意,我们可以选择“是倍数”或“大于或等于”来验证命中计数。

假设有一种情况,我们需要在三次迭代后暂停执行并检查产品列表值。因此,我们选择“命中计数”选项作为条件,并在第二个下拉列表中选择“等于”选项,并在其旁边的文本框中键入 3。这意味着当循环第三次运行时,执行将在第 27 行暂停,从而命中断点。运行应用程序并等待断点命中。

请注意,条件信息是实时的。它显示当前的命中计数。当命中计数为 3 时,应用程序在调试点停止。此时,计数也可以更改,让我们将其更改为 4,或者可以简单地重置,并且仍然可以使用数据工具提示来查看变量。如果我们将鼠标悬停在产品列表上,我们可以看到它已经包含两个产品 (prod),因此我们必须在循环的第三次迭代中,因为我们在添加到列表之前中断。

Visual Studio 2015 断点配置的一个有趣功能是,如果断点被意外删除,可以使用 Ctrl+Z 再次应用它。

如果我们想在特定的命中计数或某个特定的命中间隔处命中断点,则可以随时使用带有命中计数的断点条件。这通常在处理项目列表和递归方法时很有用。即使应用程序仍在运行,也可以选择添加另一个条件,让我们通过条件表达式添加它。我们将通过在此处添加条件表达式来检查这一点。假设我们希望当 prod 实例的产品代码为“0004”时命中断点。因此,当应用程序在断点处停止时,单击“添加条件”选项并添加条件表达式。

您可以添加多个条件并为所需的调试配置断点,以提高生产力。单击“添加条件”选项时,会添加一个新行,其中包含前面在应用“命中计数”断点时显示的所有可用选项。选择“条件表达式”选项,并在 prod.ProductCode=="0004" 为 true 时对其进行验证。请注意,您可以在表达式文本框中写入任何表达式。表达式可以是简单的,也可以是复杂的,带有多个 && 和 || 条件。此外,在键入时,IntelliSense 也会工作并帮助创建表达式。

如果您愿意,可以删除先前的命中计数条件,否则调试点将被多次命中。我在这里删除了先前的条件。运行应用程序,您将看到当断点处提到的条件变为真时,断点被命中。

我们在这里看到,一旦产品代码为“0004”的条件满足,执行就会立即停止。

Actions

让我们看看“操作”是如何工作的。默认情况下,当条件为真时,调试器将在特定断点处暂停。此行为也可以通过检查操作进行配置。可以选择记录消息,在提供的“消息”字段中输入所需的消息。

我们还可以输入我们选择的所需纯文本,并自定义消息以提高可读性和理解性。在这里可以使用美元符号 ($) 来显示系统值。当您在消息字段中键入美元符号时,您将获得可用于记录消息的所有伪变量的列表。

花括号 {} 用于显示来自应用程序或代码库的输出或变量,您还可以在消息字段中获得 IntelliSense 支持。您可以在输出窗口中记录消息。让我们尝试一下,尝试在此断点条件下记录一些内容。您还可以选择“继续执行”。此选项可防止调试器在每次命中断点时暂停。如果您想在不停止在断点处的情况下记录消息,可以选择此选项。

在“操作”消息字段中,我尝试在 prod 的产品代码 == "0004" 的条件为真时记录一条消息。我已经将消息字段配置为记录 $Function$TID$TNAME 以及 {prod}(即产品实例)和 prod.ProductCode。请注意,我还使用了纯文本,如“Method : ”、“Product Instance”、“Product Code”来使我的消息更具可读性。我选择在不停止在断点处的情况下继续执行。让我们运行应用程序,看看会发生什么。

我们在“消息”字段中定义的所有信息都按预期记录在输出窗口中。所有详细信息以及我使用的纯文本都按照定义的相同顺序记录。您可以在每次命中断点时想要显示信息时随时使用“记录消息”操作。

全新改进的错误列表

Visual Studio 2015 中的新“错误列表”现在得到了很大的改进,您可以在其中获取编译器和代码分析错误和警告的实时列表。“错误列表”的主要改进包括显示错误代码,并链接到该问题的文档。您可以单击该链接在线查看文档。筛选功能已大大扩展。仍然可以按当前项目或文档进行筛选,但现在也可以按错误严重性、错误代码、一组项目或一组文件进行筛选。

Visual Studio 2015 中已删除最大错误限制。以前,当错误数量过多时,无法真正一次性知道有多少错误。每次我们修复一定数量的错误时,编译时都会显示更多错误。现在,您的所有错误和警告将一次性显示在“错误列表”中。让我们实际尝试查看错误列表的改进。我故意在 program.cs 类的 Main 方法中进行了一些更改以获取一些错误和警告。我从产品声明中删除了 var,添加了一个空的 catch 块和一个空的 finally 块。在编译代码之前,我还启用了“在生成时启用代码分析”选项。您可以通过右键单击您的项目,打开属性并在属性窗口中选择“代码分析”选项来找到此选项,通常它显示在最后,如图所示。

现在,当我们编译该代码时,我们按预期获得了一些错误和警告。

我们在这里看到我们从编译器以及代码分析器获得了错误和警告。CS 作为错误/警告代码的前缀表示它是通过编译器生成的,而 CC 在此处表示代码分析器。我们获得了所有预期的警告和错误。请注意,错误和警告具有各自的符号。顶部的选项卡显示 2 个错误、5 个警告和 1 条消息。您可以选择这些选项来筛选并查看您需要的内容。假设您不想看到警告和消息,那么您可以单击上面的相应选项卡以仅查看错误列表。请注意,每个错误代码都是链接的形式,当您单击任何错误代码时,它会将您重定向到其文档页面。让我们单击 CS 0103,即第一个错误“名称‘products’在当前上下文中不存在”。

我们看到该链接已重定向到 MSDN 链接,其中包含该错误的详细文档。

筛选功能已进一步扩展,可以按错误、警告和严重性进行筛选。要检查,只需单击错误列表的列顶部,其中显示错误/警告符号。

一旦您单击顶部,如上图所示,筛选选项将出现在那里,您可以单击该筛选图标以查看更多可用筛选的类型。

您可以通过选中或取消选中复选框来根据您的选择筛选列表。筛选选项广泛适用于代码和项目。您可以特别选择要包含的代码,如下图所示:

或者选择作为筛选器的项目或文件。

因此,您可以看到筛选选项已扩展以处理多个选项,从而提高了开发人员的控制、配置和生产力。

结论

在本文中,我们介绍了 Visual Studio 2015 中新的改进的调试技术。我们涵盖了具有几个实际场景的断点配置,并初步了解了新的改进的错误列表。这些选项也可以在 Visual Studio 的早期版本中找到,但 VS 2015 提供了改进且更易于发现的版本。在下一篇文章中,我们将介绍剩余的两个调试选项:PerfTips 和新的诊断工具窗口。

© . All rights reserved.