了解如何使用 Visual Studio 调试 C# 代码
了解如何使用 Visual Studio 调试 C# 代码
https://docs.microsoft.com/zh-cn/visualstudio/get-started/csharp/tutorial-debugger?view=vs-2017
在本教程中,你将:In this tutorial, you will:
- 启动调试器并命中断点。Start the debugger and hit breakpoints.
- 了解在调试器中逐步执行代码的命令Learn commands to step through code in the debugger
- 检查数据提示和调试器窗口中的变量Inspect variables in data tips and debugger windows
- 检查调用堆栈Examine the call stack
系统必备Prerequisites
-
须安装 Visual Studio 2017 且具有“.NET 桌面开发”工作负载。You must have Visual Studio 2017 installed and the .NET desktop development workload.
如果尚未安装 Visual Studio,请转到 Visual Studio 下载 页免费安装。If you haven't already installed Visual Studio, go to the Visual Studio downloads page to install it for free.
如果需要安装工作负载,但已有 Visual Studio,则单击“新建项目”对话框左窗格中的“打开 Visual Studio 安装程序”链接(选择“文件” > “新建” > “项目”)。If you need to install the workload but already have Visual Studio, click the Open Visual Studio Installer link in the left pane of the New Project dialog box (select File > New > Project). Visual Studio 安装程序启动。The Visual Studio Installer launches. 选择“.NET 桌面开发”工作负载,然后选择“修改”。Choose the .NET desktop development workload, then choose Modify.
创建项目Create a project
-
在 Visual Studio 中,依次选择“文件”>“新建项目”。In Visual Studio, choose File > New Project.
-
在“Visual C#”下,选择“Windows 桌面”,然后在中间窗格中选择“控制台应用”。Under Visual C#, choose Windows Desktop, and then in the middle pane choose Console App.
如果没有看到“控制台应用程序”项目模板,请单击“新建项目”对话框左侧窗格中的“打开 Visual Studio 安装程序”链接。If you don't see the Console Application project template, click the Open Visual Studio Installer link in the left pane of the New Project dialog box. Visual Studio 安装程序启动。The Visual Studio Installer launches. 选择“.NET 桌面开发”工作负载,然后选择“修改”。Choose the .NET desktop development* workload, then choose Modify.
-
键入名称(如“get-started-debugging”),然后单击“确定”。Type a name like get-started-debugging and click OK.
Visual Studio 随即创建项目。Visual Studio creates the project.
-
在 Program.cs 中,将以下代码In Program.cs, replace the following code
C#复制
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace get_started_debugging { class Program { static void Main(string[] args) { } } }
替换为此代码:with this code:
C#复制
using System; using System.Collections.Generic; public class Shape { // A few example members public int X { get; private set; } public int Y { get; private set; } public int Height { get; set; } public int Width { get; set; } // Virtual method public virtual void Draw() { Console.WriteLine("Performing base class drawing tasks"); } } class Circle : Shape { public override void Draw() { // Code to draw a circle... Console.WriteLine("Drawing a circle"); base.Draw(); } } class Rectangle : Shape { public override void Draw() { // Code to draw a rectangle... Console.WriteLine("Drawing a rectangle"); base.Draw(); } } class Triangle : Shape { public override void Draw() { // Code to draw a triangle... Console.WriteLine("Drawing a trangle"); base.Draw(); } } class Program { static void Main(string[] args) { var shapes = new List<Shape> { new Rectangle(), new Triangle(), new Circle() }; foreach (var shape in shapes) { shape.Draw(); } // Keep the console open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); } } /* Output: Drawing a rectangle Performing base class drawing tasks Drawing a triangle Performing base class drawing tasks Drawing a circle Performing base class drawing tasks */
启动调试器!Start the debugger!
-
按 F5(“调试”>“开始调试”)或调试工具栏中的“开始调试”按钮()。Press F5 (Debug > Start Debugging) or the Start Debugging button in the Debug Toolbar.
通过 F5 启动应用时,调试器会附加到应用进程,但现在我们还未执行任何特殊操作来检查代码。F5 starts the app with the debugger attached to the app process, but right now we haven't done anything special to examine the code. 因此应用只会加载,控制台输出如你所见。So the app just loads and you see the console output.
cmd复制
Drawing a rectangle Performing base class drawing tasks Drawing a triangle Performing base class drawing tasks Drawing a circle Performing base class drawing tasks
在本教程中,我们将使用调试器仔细查看此应用,并查看调试器功能。In this tutorial, we'll take a closer look at this app using the debugger and get a look at the debugger features.
-
按红色的停止()按钮来停止调试器。Stop the debugger by pressing the red stop button.
设置断点并启动调试器Set a breakpoint and start the debugger
-
在
Main
函数的foreach
循环中,通过单击以下代码行的左边距来设置断点:In theforeach
loop of theMain
function, set a breakpoint by clicking the left margin of the following line of code:shape.Draw()
设置断点的位置会出现一个红色圆圈。A red circle appears where you set the breakpoint.
断点是可靠调试的最基本和最重要的功能。Breakpoints are the most basic and essential feature of reliable debugging. 断点指示 Visual Studio 应在哪个位置挂起你的运行代码,以使你可以查看变量的值或内存的行为,或确定代码的分支是否运行。A breakpoint indicates where Visual Studio should suspend your running code so you can take a look at the values of variables, or the behavior of memory, or whether or not a branch of code is getting run.
-
按“F5”或“开始调试”按钮,应用随即启动,调试器将运行到你设置断点的代码行。Press F5 or the Start Debugging button , the app starts, and the debugger runs to the line of code where you set the breakpoint.
黄色箭头表示调试器暂停处的语句,它还在同一点上暂停应用执行(此语句尚未执行)。The yellow arrow represents the statement on which the debugger paused, which also suspends app execution at the same point (this statement has not yet executed).
如果应用尚未运行,则按 F5 会启动调试器并在第一个断点处停止。If the app is not yet running, F5 starts the debugger and stops at the first breakpoint. 否则,按 F5 将继续运行应用至下一个断点。Otherwise, F5 continues running the app to the next breakpoint.
当你知道要详细检查的代码行或代码段时,断点功能非常有用。Breakpoints are a useful feature when you know the line of code or the section of code that you want to examine in detail.
使用单步执行命令在调试器中导航代码Navigate code in the debugger using step commands
大多数情况下,我们使用键盘快捷方式,因为这是在调试器中快速执行应用的好方法(括号中显示了等效的命令,如菜单命令)。Mostly, we use the keyboard shortcuts here, because it's a good way to get fast at executing your app in the debugger (equivalent commands such as menu commands are shown in parentheses).
-
在
Main
方法中的shape.Draw
方法调用中暂停时,按 F11(或选择“调试”>“单步执行”)前进到Rectangle
类的代码。While paused in theshape.Draw
method call in theMain
method, press F11 (or choose Debug > Step Into) to advance into code for theRectangle
class.F11 是“单步执行”命令,每单击一次,应用就执行一个语句。F11 is the Step Into command and advances the app execution one statement at a time. F11 是一种以最详尽方式检查执行流的好方法。F11 is a good way to examine the execution flow in the most detail. (为了更快地浏览代码,我们还向你展示一些其他选项。)默认情况下,调试器会跳过非用户代码(如果需要更多详细信息,请参阅仅我的代码)。(To move faster through code, we show you some other options also.) By default, the debugger skips over non-user code (if you want more details, see Just My Code).
-
按几次 F10(或选择“调试”>“单步跳过”),直到调试器停止于
base.Draw
方法调用,然后再按一次 F10。Press F10 (or choose Debug > Step Over) a few times until the debugger stops on thebase.Draw
method call, and then press F10 one more time.请注意,这次调试器不会单步执行基类 (
Shape
) 的Draw
方法。Notice this time that the debugger does not step into theDraw
method of the base class (Shape
). 按 F10 将使调试器前进,但不会单步执行应用代码中的函数或方法(代码仍将执行)。F10 advances the debugger without stepping into functions or methods in your app code (the code still executes). 通过在进行base.Draw
方法调用时按“F10”(而不是“F11”),我们跳过了base.Draw
的实现代码(我们现在可能对此不感兴趣)。By pressing F10 on thebase.Draw
method call (instead of F11), we skipped over the implementation code forbase.Draw
(which maybe we're not interested in right now).
使用“运行时单击”导航代码Navigate code using Run to Click
-
在代码编辑器中,向下滚动并将鼠标悬停在
Triangle
类中的Console.WriteLine
方法上,直到左侧出现绿色的“运行时单击”按钮()。In the code editor, scroll down and hover over theConsole.WriteLine
method in theTriangle
class until the green Run to Click button appears on the left. 按钮的工具提示显示“将执行运行到此处”。The tooltip for the button shows "Run execution to here".备注
“运行时单击”是 Visual Studio 2017Visual Studio 2017 中的新增按钮。The Run to Click button is new in Visual Studio 2017Visual Studio 2017. 如果未看到绿色箭头按钮,请在此示例中改为使用 F11 以使调试器前进到正确的位置。If you don't see the green arrow button, use F11 in this example instead to advance the debugger to the right place.
-
单击“运行时单击”按钮()。Click the Run to Click button .
使用此按钮类似于设置临时断点。Using this button is similar to setting a temporary breakpoint. “运行时单击”对于快速到达应用代码的可见区域十分方便(你可在任何打开的文件中单击)。Run to Click is handy for getting around quickly within a visible region of app code (you can click in any open file).
调试器前进到
Triangle
类的Console.WriteLine
方法实现。The debugger advances to theConsole.WriteLine
method implementation for theTriangle
class.暂停时,你注意到有拼写错误!While paused, you notice a typo! “Drawing a trangle”输出拼写错误。The output "Drawing a trangle" is misspelled. 在调试器中运行应用时,我们可直接在此处修复它。We can fix it right here while running the app in the debugger.
编辑代码并继续调试Edit code and continue debugging
-
单击“Drawing a trangle”内并键入校正,将“trangle”更改为“triangle”。Click into "Drawing a trangle" and type a correction, changing "trangle" to "triangle".
-
按一次 F11,你会看到调试器再次前进。Press F11 once and you see that the debugger advances again.
备注
根据你在调试器中编辑的代码类型,可能会看到一条警告消息。Depending on what type of code you edit in the debugger, you may see a warning message. 在某些情况下,代码需要重新编译才能继续。In some scenarios, the code will need to recompile before you can continue.
单步跳出Step out
假设你已完成了对 Triangle
类中 Draw
方法的检查,并且希望退出该函数但保持位于调试器中。Let's say that you are done examining the Draw
method in the Triangle
class, and you want to get out of the function but stay in the debugger. 可使用“单步跳出”命令执行此操作。You can do this using the Step Out command.
-
按 Shift + F11(或“调试”>“单步跳出”)。Press Shift + F11 (or Debug > Step Out).
此命令将恢复应用执行(并使调试器前进),直到当前函数返回。This command resumes app execution (and advances the debugger) until the current function returns.
你应当会回到
Main
方法的foreach
循环中。You should be back in theforeach
loop in theMain
method.
快速重启应用Restart your app quickly
单击调试工具栏中的“重启”()按钮(Ctrl + Shift + F5)。Click the Restart button in the Debug Toolbar (Ctrl + Shift + F5).
当你按下“重启”时,与停止应用并重启调试器相比,它节省了时间。When you press Restart, it saves time versus stopping the app and restarting the debugger. 调试器在执行代码命中的第一个断点处暂停。The debugger pauses at the first breakpoint that is hit by executing code.
调试器再次在你在 shape.Draw()
方法上设置的断点处停止。The debugger stops again at the breakpoint you set, on the shape.Draw()
method.
使用数据提示检查变量Inspect variables with data tips
允许你检查变量的功能是调试器最有用的功能之一,并且有不同的方法来执行此操作。Features that allow you to inspect variables are one of the most useful features of the debugger, and there are different ways to do it. 通常,当尝试调试问题时,你试图找出变量是否存储了你期望它们在特定时间具有的值。Often, when you try to debug an issue, you are attempting to find out whether variables are storing the values that you expect them to have at a particular time.
-
在
shape.Draw()
方法上暂停时,将鼠标悬停在shape
对象上,你会看到其默认属性值Rectangle
对象类型。While paused on theshape.Draw()
method, hover over theshape
object and you see its default property value, which is the object typeRectangle
. -
展开
shape
对象以查看其属性,例如Height
属性,其值为 0。Expand theshape
object to see its properties, such as theHeight
property, which has a value of 0. -
按几次 F10(或选择“调试” > “单步跳过”),在
foreach
循环中重复一次,在shape.Draw()
上再次暂停。Press F10 (or Debug > Step Over) a few times to iterate once through theforeach
loop, pausing again onshape.Draw()
. -
将鼠标再次悬停在形状对象上,这一次会看到一个类型为
Triangle
的新对象。Hover over the shape object again, and this time you see that you have a new object with a typeTriangle
.通常情况下,在调试时,需要快速检查变量的属性值,以查看它们是否存储了你希望它们存储的值,可根据数据提示执行此操作。Often, when debugging, you want a quick way to check property values on variables, to see whether they are storing the values that you expect them to store, and the data tips are a good way to do it.
使用“自动”和“局部变量”窗口检查变量Inspect variables with the Autos and Locals windows
-
查看代码编辑器底部的“自动”窗口。Look at the Autos window at the bottom of the code editor.
如果已关闭,请依次选择“调试” > “Windows” > “自动”,在调试器中暂停时将其打开。If it is closed, open it while paused in the debugger by choosing Debug > Windows > Autos.
-
展开
shapes
对象。Expand theshapes
object.在“自动”窗口中,可看到变量及其当前值。In the Autos window, you see variables and their current value. “自动”窗口显示当前行或前一行使用的所有变量(检查文档中特定于语言的行为)。The Autos window shows all variables used on the current line or the preceding line (Check documentation for language-specific behavior).
-
接下来,我们来看看“自动”窗口旁边的选项卡中的“局部变量”窗口。Next, look at the Locals window, in a tab next to the Autos window.
“局部变量”窗口显示当前作用域中的变量,即当前执行上下文。The Locals window shows you the variables that are in the current scope, that is, the current execution context.
设置监视Set a watch
-
在主代码编辑器窗口中,右键单击
shapes
对象,然后选择“添加监视”。In the main code editor window, right-click theshapes
object and choose Add Watch.“监视”窗口将在代码编辑器的底部打开。The Watch window opens at the bottom of the code editor. 可使用“监视”窗口指定要关注的变量(或表达式)。You can use a Watch window to specify a variable (or an expression) that you want to keep an eye on.
现在,你在
shapes
对象上设置好了监视,当你在调试器中移动时,可看到其值发生变化。Now, you have a watch set on theshapes
object, and you can see its value change as you move through the debugger. 与其他变量窗口不同,“监视”窗口始终显示你正在监视的变量(当超出作用域时,它们会变灰)。Unlike the other variable windows, the Watch window always shows the variables that you are watching (they're grayed out when out of scope).
检查调用堆栈Examine the call stack
-
在
foreach
循环中暂停时,单击“调用堆栈”窗口,默认情况下,该窗口在右下方窗格中打开。While paused in theforeach
loop, click the Call Stack window, which is by default open in the lower right pane.如果已关闭,请依次选择“调试” > “Windows” > “调用堆栈”,在调试器中暂停时将其打开。If it is closed, open it while paused in the debugger by choosing Debug > Windows > Call Stack.
-
单击 F11 几次,直到在代码编辑器中
Triangle
类的Base.Draw
方法中看到调试器暂停。Click F11 a few times until you see the debugger pause in theBase.Draw
method for theTriangle
class in the code editor. 查看“调用堆栈”窗口。Look at the Call Stack window.“调用堆栈”窗口显示方法和函数被调用的顺序。The Call Stack window shows the order in which methods and functions are getting called. 最上面一行显示当前函数(此应用中的
Triangle.Draw
方法)。The top line shows the current function (theTriangle.Draw
method in this app). 第二行显示Triangle.Draw
是从Main
方法调用的,依此类推。The second line shows thatTriangle.Draw
was called from theMain
method, and so on.备注
“调用堆栈”窗口类似于某些 IDE(如 Eclipse)中的调试透视图。The Call Stack window is similar to the Debug perspective in some IDEs like Eclipse.
调用堆栈是检查和理解应用执行流的好方法。The call stack is a good way to examine and understand the execution flow of an app.
可双击代码行来查看该源代码,这也会更改调试器正在检查的当前作用域。You can double-click a line of code to go look at that source code and that also changes the current scope being inspected by the debugger. 此操作不会使调试器前进。This action does not advance the debugger.
还可使用“调用堆栈”窗口中的右键单击菜单执行其他操作。You can also use right-click menus from the Call Stack window to do other things. 例如,你可将断点插入到指定的函数中,使用“运行到光标处”推进调试器,然后检查源代码。For example, you can insert breakpoints into specified functions, advance the debugger using Run to Cursor, and go examine source code. 有关详细信息,请参阅如何:检查调用堆栈。For more information, see How to: Examine the Call Stack.
更改执行流Change the execution flow
-
在
Circle.Draw
方法调用中暂停调试器后,使用鼠标抓住左侧的黄色箭头(执行指针),将黄色箭头向上移动一行到Console.WriteLine
方法调用。With the debugger paused in theCircle.Draw
method call, use the mouse to grab the yellow arrow (the execution pointer) on the left and move the yellow arrow up one line to theConsole.WriteLine
method call. -
按下 F11。Press F11.
调试器将重新运行
Console.WriteLine
方法(你会在控制台窗口输出中看到)。The debugger reruns theConsole.WriteLine
method (you see this in the console window output).通过更改执行流,你可以进行测试不同代码执行路径或重新运行代码等操作,而无需重启调试器。By changing the execution flow, you can do things like test different code execution paths or rerun code without restarting the debugger.
警告
通常你需要小心使用此功能,工具提示中会出现警告。Often you need to be careful with this feature, and you see a warning in the tooltip. 你也可能会看到其他警告。You may see other warnings, too. 移动指针无法将应用程序还原到更早的应用状态。Moving the pointer cannot revert your application to an earlier app state.
-
按 F5 继续运行应用。
上一篇: mybatis的基本了解
下一篇: Flask学习笔记(三)