在这篇文章中,咱们假定读者了解VS
基本的调试知识,如:git
许多开发人员使用这个功能强大的工具包来处理调试会话。然而,Visual Studio
调试工具提供了更多的功能。下面是一系列Visual Studio调试效率技巧。注意,这些提示和快捷方式已经在的Visual studio 2019 16.6 EN-US版本中进行了验证,验证时Visual studio
没有安装扩展。github
使用快捷键Ctrl+F10
,您可让调试器运行到光标所在行位置。多线程
在调试运行的程序时,经过鼠标悬停在当前行的代码上时,出现绿色的符号,能够点击此符号,直接让断点运行到此处。
app
在调试运行的程序时,经过鼠标悬停在当前行的代码上时,经过按住Ctrl
键转换为将此处做为下一条要执行的语句。它与经过绿色箭头符号运行到这里不一样,此功能将会跳过中间的语句,直接将断点跳转到此处。所以,在下面的动图中,咱们能够在监视窗口中引用obj仍然为null,中间的MyClass
构造函数并无被执行。
编辑器
当你设置一个非静态的设置器为断点时,当全部对象的属性的值发生更改时触发断点。经过局部窗口(监视器窗口)右键点击:值更改时中断
菜单,单个对象也能够得到相同的行为。ide
下面的动画说明了这个功能,只有当obj2.Prop
发生变化时,命中断点,而obj1.Prop
发生变化时没有命中断点。函数
注意:数据断点绑定到活动对象时,旨在调试期间起做用。所以,一旦调试过程中止,设置的断点就会丢失,在之后的调试过程当中不能重用它。工具
能够将条件附加到断点中,以便尽在特定场景中触发中断。在下面的动图中,咱们在循环中定义条件i>6
的断点。而后点击继续
,能够看到一旦断点中止,i
的值实际上变成了7
。oop
在遇到断点时,中止程序执行时最多见的操做。可是,你能够选择在输出窗口中不终止(或带终止)打印一些跟踪信息。下面的动图说明了这种可能性。咱们在输出窗口中跟踪i从0到9的值。注意:跟踪断点在编辑器的断点显示位置显示为菱形形状。动画
注意,条件和跟踪操做均可以在断点上指定。
在监视窗口中,经过当前执行范文内引用的名称来跟踪对象。可是,当这样的跟踪引用超出做用域时,即便在引用对象仍处于活动状态时,它在监视窗口的上下文也不安的毫无心义而且被禁用。
在许多状况下,咱们想继续跟踪做用域外对象的状态。为此,请在监视窗口中右键单击此类引用,单击菜单[Make Object ID] 建立对象ID(M)
,并要在监视器中添加$1(或者$2,$3,...,取决于你已经建立了多个对象ID)。
下面的动图演示了如何跟踪做用域外对象的属性获取器的状态,该属性获取器以字符串的形式返回实际的日期时间。它很好地显示了当引用obj
在Fct()
上下文中超出做用域时,要观看的obj
项将被禁用,而$1
仍然会得到更新。
函数返回的值有时在源代码中被忽略,或者有时这个值在调试时没法被显示的访问。
这样的返回值能够显示在调试->窗口->自动窗口
中。伪变量$ReturnValue
也能够在即时窗口和监视窗口中使用,以方便查看最后一个函数调用的返回值。
注意,菜单调试->窗口->自动窗口
仅在Visual Studio
调试器附加到进程而且程序被调试器暂停时可用。
从Visual Studio 2017
开始,从新附加到进程Shift+Alt+P
工具被提出,而且很是方便。将调试器附加到某个进程后,Visual Studio
会记住它,并建议将调试器从新附加到同一进程。斜体也同样,由于这里有一个关于进程标识的启发式方法:
Visual Studio
将尝试查找和前一个进程名具备相同名称的单进程,并将调试器从新附加到该进程。从新附加到进程也适用于涉及多个进程的调试会话。在这种状况下,Visual Studio
会尝试使用上述相同的启发式方法来查找它附加到的全部进程。
No-Side-Effect
评估有时,在即时窗口或监视窗口中评估表达式时,某些状态会更改。这种行为一般时不但愿发生的。你不想仅仅由于须要评估表达式的值而破坏调试程序的状态。这种状况被称为Heisenbug
,该术语时物理学家Werner Heisenberg
的双关语,它首先断言了量子力学的观察者效应,该现象指出,观察系统的行为不可避免的会改变器状态。
为了不更改任何状态,你能够在表达式后面加上nse
(No-Side-Effect)。下面的动图说明了这种可能性(在监视窗口中监视State
的值是否有变化)。
下面这种动图是nse
在监视窗口的使用。因为SideEffectFct()
所观察的项中有Refresh
评估按钮,因此此示例比前一个示例更简单。
调试多线程应用程序是有名的复杂。但愿在源码中显示线程
按钮能提供很大的帮助。它在编辑器的左侧边栏引入标记图标,以跟踪其余线程被暂停的位置。这个标记能够用来显示线程ID
,并最终切换到另外一个线程。注意:若是至少两个线程在同一位置暂停,则会显示不一样的标记符号。
更多调试多线程应用程序的技巧能够在这个微软文档中找到:Get started debugging multithreaded applications (C#, Visual Basic, C++)
下面是这个演示的源代码,若是你想演示它,能够进行参考:
using System; using System.Threading; class Program { static void Main() { for (int i=0; i< 5; i++) { // Avoid capturing a loop variable in the lambda below int j = i; // So 2 thread are blocked on '0' case if (j == 1) { j = 0; } ThreadPool.QueueUserWorkItem(delegate { Method(j); }); } Thread.Sleep(60000); } static void Method(int id) { switch(id) { case 0: Thread.Sleep(60000); break; case 1: Thread.Sleep(60000); break; case 2: Thread.Sleep(60000); break; case 3: Thread.Sleep(60000); break; case 4: Thread.Sleep(60000); break; } } }
咱们常常依赖一些黑盒组件:咱们没有源代码的组件。
可是,在调试复杂行为时,观察甚至调试引用的黑盒组件引用的逻辑。这就是为何从16.5版本开始,Visual Studio 2019
能够从编译好的程序中生成一些源代码。这样的源代码是能够调试的。这个特性是基于开源软件(OSS)工程:ILSpy(https://github.com/icsharpcode/ILSpy)。
反编译菜单能够在模块窗口的组件右键菜单(以下面的动图所示)和Source Not Found
或No Symbols Loaded
对话框中给出。
将IL
代码反编译为源代码不多是完美的,由于一些源代码信息在编译时丢失了。所以,这个特性有一些限制,在这个官方文档的最后会解释:Generate source code from .NET assemblies while debugging
https://docs.microsoft.com/en-us/visualstudio/debugger/decompilation?view=vs-2019
Visual Studio很是出色,在调试方面尤为出色。 在这里,我试图选择一些既隐藏又常常有用的技巧,但愿它们能帮助您提升生产率。
若是你感受有用,请关注一下个人公众号