Visual Studio 2015 中 LINQ 和 Lambda 的工具窗口支持,PerfTip 和诊断工具窗口





5.00/5 (9投票s)
本文将介绍 VisualStudio 2015 的其他调试改进,例如 LINQ 和 Lambda 表达式的工具窗口支持、新的 PerfTips 以及新的诊断工具窗口。
引言
本文是 调试改进 - 系列第五天 的续篇。系列的前一部分介绍了 Visual Studio 2015 中的断点配置改进和新的改进错误列表等主题。本文将介绍 Visual Studio 2015 的其他调试改进,例如 LINQ 和 Lambda 表达式的工具窗口支持、新的 PerfTips 以及新的诊断工具窗口。
学习 Visual Studio 2015 系列
- 第 1 天:Visual Studio 2015 中的代码辅助
- 第 2 天:Visual Studio 2015 中的代码分析器
- 第 3 天:Visual Studio 2015 中的重命名辅助
- 第 4 天:Visual Studio 2015 中的代码重构
- 第 5 天:Visual Studio 2015 中的调试改进(断点配置和新错误列表)
- 第 6 天:Visual Studio 2015 中的调试改进(LINQ 和 Lambda 的工具窗口支持、PerfTips、诊断工具窗口)
必备组件
本文教程中使用了 Visual Studio 2015 Express 来解释概念和功能。为了方便示例和练习,我们创建了一个 Visual Studio 解决方案,其中包含一个名为 VS2015ConsoleApplication 的控制台应用程序。该控制台应用程序包含一个 MyProduct
类,该类将产品作为特定于实体的基本操作,例如获取产品并返回产品列表,如下所示。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VS2015ConsoleApplication
{
public class MyProducts :IProducts
{
List<Product> _allProduct = new List<Product>();
public MyProducts()
{
_allProduct.Add(new Product {ProductCode="0001",ProductName="IPhone",ProductPrice="60000",ProductType="Phone",ProductDescription="Apple IPhone" } );
_allProduct.Add(new Product { ProductCode = "0002", ProductName = "Canvas", ProductPrice = "20000", ProductType = "Phone", ProductDescription = "Micromax phone" });
_allProduct.Add(new Product { ProductCode = "0003", ProductName = "IPad", ProductPrice = "30000", ProductType = "Tab", ProductDescription = "Apple IPad" });
_allProduct.Add(new Product { ProductCode = "0004", ProductName = "Nexus", ProductPrice = "30000", ProductType = "Phone", ProductDescription = "Google Phone" });
_allProduct.Add(new Product { ProductCode = "0005", ProductName = "S6", ProductPrice = "40000", ProductType = "Phone", ProductDescription = "Samsung phone" });
}
/// <summary>
/// FetchProduct having price greater that 3000
/// </summary>
/// <returns></returns>
public List<Product> FetchProduct() => (from p in _allProduct where Convert.ToInt32(p.ProductPrice) > 30000 select p).ToList();
/// <summary>
/// FetchProduct
/// </summary>
/// <param name="pCode"></param>
/// <returns></returns>
public Product FetchProduct(string pCode)
{
return _allProduct.Find(p => p.ProductCode == pCode);
}
/// <summary>
/// FetchProduct with productCode and productName
/// </summary>
/// <param name="productCode"></param>
/// <param name="productName"></param>
/// <returns></returns>
public Product FetchProduct(string productCode, string productName)
{
return _allProduct.Find(p => p.ProductCode == productCode && p.ProductName==productName);
}
public List<Product> GetProductList()
{
return _allProduct;
}
}
}
其中 IProducts
是一个简单的接口。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VS2015ConsoleApplication
{
interface IProducts
{
Product FetchProduct(string productCode);
Product FetchProduct(string productCode,string productName);
List<Product> GetProductList();
}
}
在下面的 Program.cs 文件中,调用 FetchProduct()
方法以获取所有产品的列表。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VS2015ConsoleApplication
{
class Program
{
static void Main()
{
var myProducts = new MyProducts();
var allProducts = myProducts.GetProductList();
Console.ReadLine();
}
}
}
LINQ 和 Lambda 表达式的工具窗口支持
这是 Visual Studio 2015 带来的最佳改进之一。在早期版本的 Visual Studio 中,当开发人员尝试在立即窗口或监视窗口中执行/编写 LINQ 或 Lambda 表达式时,代码不支持,并会显示一条消息,指出不允许在立即窗口或监视窗口中使用 LINQ 和 Lambda 表达式。有了新发布的 Visual Studio 2015,这一限制已得到解决。现在,开发人员可以自由地在立即窗口中执行 LINQ 和 Lambda 表达式。此功能在运行时调试代码时非常有用,因为您可以在运行时在立即窗口中编写 LINQ 查询来选择或过滤列表或对象。
让我们通过实际示例来涵盖这个主题。我们已经有了一个包含一个获取产品列表的控制台应用程序的解决方案。要实际检查此工具支持功能,请在 program.cs 中的 Console.ReadLine()
处设置一个断点,即在获取列表时。
当我们悬停并尝试查看所有产品时,会看到如下所示的产品列表。
现在,假设出现一种情况,开发人员希望在此断点执行某些调试操作,例如检查每个产品实体中的产品名称、产品价格,或者需要查看价格大于 30000 的产品,那么开发人员必须显式地导航打开的窗口中的每个列表项,如下所示。
上述调试和导航方法非常耗时。考虑一个包含数千条记录的列表。现在,您可以利用立即窗口中对 LINQ 和 Lambda 表达式的支持来加快调试需求。假设我们需要获取列表中所有 ProductName
的列表。让我们看看如何在立即窗口中做到这一点。
打开立即窗口。您可以通过 Visual Studio 的“调试”菜单打开它,如下所示。即 Debug->Windows->Immediate,或者您可以使用默认的键盘快捷键打开窗口,即 Ctrl+Alt+I。
立即窗口将在类文件的底部打开,您可以在代码执行暂停在断点处时,在窗口中键入 allProducts 来查看产品列表。您将看到与悬停在 allProducts
变量上时看到的产品列表。
现在,让我们编写一个 LINQ 查询来从产品列表中获取所有产品名称,然后按 Enter。请注意,通过此 LINQ 查询会立即获取一个 ProductName
列表。
(from p in allProducts select p.ProductName).ToList();
同样,您也可以对列表执行过滤或执行您需要的任何 LINQ 查询以进行调试。
在早期版本中,立即窗口不支持 LINQ。现在,让我们尝试使用 Lambda 表达式进行此操作。
allProducts.Select(p=>p.ProductName).ToList();
我们得到了相同的结果。
这是调试集合或对象的一个极其有用的功能。您也可以在监视窗口中使用 LINQ 和 Lambda。
新的 PerfTips 功能
Visual Studio 2015 中的新 PerfTips 功能提供以性能为中心的信息。开发人员无需依赖任何工具、代码或秒表实现即可获取性能相关信息。在调试代码时,PerfTips 功能以工具提示的形式显示性能信息。工具提示显示代码运行的时间跨度。在单步执行代码时,它会显示该单步执行期间代码运行的时间跨度。即使我们从断点运行到断点,PerfTip 功能也会显示两个断点之间代码运行的时间跨度。让我们通过实际示例来涵盖此功能。我已经将 Program.cs 文件的 Main
方法更改为以下内容。
static void Main()
{
var myProducts = new MyProducts();
var allProducts = myProducts.GetProductList();
foreach (var prod in allProducts)
{
Console.WriteLine(prod.ProductName);
}
foreach (var prod in allProducts)
{
if(Convert.ToInt32(prod.ProductPrice)>30000)
Console.WriteLine(String.Format("ProductName : {0} and ProductPrice : {1}",prod.ProductName,prod.ProductPrice));
}
Console.ReadLine();
}
让我们在 Program.cs 类中第一个 foreach 循环的开始处设置一个断点,假设我们想获取到达此代码行的经过时间。运行应用程序。
您可以看到 PerTips 显示已用时间小于 1 毫秒。我们没有使用任何秒表、代码或任何第三方工具来获取此经过时间。它是 Visual Studio 2015 的新 PerfTips 功能,显示程序执行到此断点所经过的时间。现在我将再次运行应用程序。但有一个改变。我在两个 foreach 循环之后都加入了 Thread.Sleep
10 毫秒,并在那里设置了断点。现在,当您运行应用程序并单步执行 Thread.Sleep(10)
断点时,PerfTips 功能将在显示上一单步执行的已用时间时,加上这 10 毫秒的已用时间。
它清楚地表明,到上一单步执行已用时间小于或等于 14 毫秒。您也可以获得两个断点之间的时间。让我们尝试一下。让我们在方法的开始处设置第一个断点,在方法的最后一行设置第二个断点。现在,当您运行应用程序时,代码执行会在第一个断点处停止。只需按 F5 或继续执行,执行将在第二个断点处暂停,从而显示整个方法执行的总经过时间。
在我们的例子中,这是少于 4 毫秒。您可以利用此功能来排查应用程序中的性能瓶颈。
诊断工具窗口
Visual Studio 中的新诊断工具窗口会在您运行调试应用程序时出现。
此窗口提供了大量信息,在调试应用程序时非常有用。它包含顶部的的时间轴,提供了应用程序调试会话的时间显示。
可以通过 Debug-> Show Diagnostic Tools 选项启动诊断工具窗口,如下图所示。
时间轴下方有三个重要视图。
- 调试器事件视图显示断点、输出和 IntelliTrace 事件。
- 内存视图以字节为单位显示处理器或内存使用情况。
- CPU 利用率视图显示处理器 CPU 使用率的百分比。
诊断工具窗口底部有选项卡,其中包含其他详细信息和选项以及过滤器。底部显示的黄色箭头表示代码当前正在调试并且已暂停在断点处。
使用现有的代码库作为示例来探索这些功能。在我们在先前文章中一直使用的现有 Program.cs 文件中的两个位置设置断点,如下所示。
现在运行应用程序,等待执行暂停在断点处。现在打开诊断工具或按 Ctrl+Alt+F2。您将看到诊断工具窗口的以下视图。
时间线
这个示例调试会话从应用程序启动到当前断点共计 0.19 秒,我们在时间轴上查看了其中的大约 5.5 秒。这里的黑色条形表示可以选定时间轴的一部分。
以白色显示的选定时间间隔是开发人员希望重点关注的时间轴区域。您可以拖动任一黑色条形来调整选定区域。此窗口的其他部分会根据黑色条形的位置进行调整。请注意,由于我们的选定区域包含断点轨道上的红色线条的一部分,因此列表还会显示该断点线的结尾。
调试器事件
诊断工具窗口中的调试器事件视图显示了在调试会话期间发生的事件。此视图分为不同的轨道。中断事件轨道显示停止应用程序执行的事件,例如命中断点、单步执行代码或中断异常。条形表示应用程序在中断事件之间运行的时间。此轨道中的条形是颜色编码的;红色表示断点或中断异常,黄色表示单步执行代码,蓝色表示全部中断操作。
蓝色条形表示从最后一个断点到使用“全部中断”功能暂停调试会话的时间。将鼠标悬停在条形上可查看已用时间。
IntelliTrace 轨道显示 IntelliTrace 收集的所有其他事件,例如 ADO.NET 调用、文件访问等。它也是颜色编码的,黑色表示重要事件,灰色表示不太重要的事件,紫色表示自定义事件。
进程内存
诊断工具窗口的进程内存部分可帮助您在调试应用程序时监控其内存使用情况。在 Visual Studio 2013 中,作为性能和诊断中心的一部分,已引入了内存使用情况工具。在 Visual Studio 2015 中,此工具已合并到诊断工具窗口中并得到了增强。与当前内存使用情况工具一样,您可以在任何时间点获取内存快照,并将其与其他快照进行比较。
在此示例调试会话中,您可以看到有一个快照。
使用内存使用情况工具可帮助您分析内存峰值或泄漏的原因。您还可以通过内存使用情况窗口查看堆信息。
CPU
诊断工具窗口的 CPU 利用率部分通过显示实时 CPU 图形,帮助您监控应用程序的 CPU 使用情况。
此图形显示了代码使用了多少 CPU 资源。通过调试器事件查看 CPU 使用情况有助于将 CPU 峰值与代码执行相关联,从而更轻松地调试与 CPU 相关的问题。
您可以切换到 CPU 分析以获取更详细的 CPU 使用情况统计信息。
您可以使用诊断工具窗口来辅助您的调试过程,并提高生产力和性能。
结论
在本文中,我们介绍了 Visual Studio 2015 的两个非常有用且关键的功能,即 PerfTip 和诊断工具窗口。我们看到了 PerfTip 如何在无需任何设置代码或外部工具的情况下,在调试过程中提供有价值的性能信息。我们看到了诊断工具窗口如何帮助您调试代码并监控 CPU 和内存使用情况。