了解如何使用 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

  1. 在 Visual Studio 中,依次选择“文件”>“新建项目”。In Visual Studio, choose File > New Project.

  2. 在“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.

  3. 键入名称(如“get-started-debugging”),然后单击“确定”。Type a name like get-started-debugging and click OK.

    Visual Studio 随即创建项目。Visual Studio creates the project.

  4. 在 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!

  1. 按 F5(“调试”>“开始调试”)或调试工具栏中的“开始调试”按钮(开始调试)。Press F5 (Debug > Start Debugging) or the Start Debugging button Start Debugging 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.

  2. 按红色的停止(停止调试)按钮来停止调试器。Stop the debugger by pressing the red stop Stop Debugging button.

设置断点并启动调试器Set a breakpoint and start the debugger

  1. Main 函数的 foreach 循环中,通过单击以下代码行的左边距来设置断点:In the foreach loop of the Main 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.

  2. 按“F5”或“开始调试”按钮开始调试,应用随即启动,调试器将运行到你设置断点的代码行。Press F5 or the Start Debugging button Start Debugging, 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.

大多数情况下,我们使用键盘快捷方式,因为这是在调试器中快速执行应用的好方法(括号中显示了等效的命令,如菜单命令)。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).

  1. Main 方法中的 shape.Draw 方法调用中暂停时,按 F11(或选择“调试”>“单步执行”)前进到 Rectangle 类的代码。While paused in the shape.Draw method call in the Main method, press F11 (or choose Debug > Step Into) to advance into code for the Rectangle class.

    使用 F11 单步执行代码Use F11 to Step Into code

    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).

  2. 按几次 F10(或选择“调试”>“单步跳过”),直到调试器停止于 base.Draw 方法调用,然后再按一次 F10。Press F10 (or choose Debug > Step Over) a few times until the debugger stops on the base.Draw method call, and then press F10 one more time.

    使用 F10 单步跳过代码Use F10 to Step Over code

    请注意,这次调试器不会单步执行基类 (Shape) 的 Draw 方法。Notice this time that the debugger does not step into the Draw 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 the base.Draw method call (instead of F11), we skipped over the implementation code for base.Draw (which maybe we're not interested in right now).

  1. 在代码编辑器中,向下滚动并将鼠标悬停在 Triangle 类中的 Console.WriteLine 方法上,直到左侧出现绿色的“运行时单击”按钮(运行时单击)。In the code editor, scroll down and hover over the Console.WriteLine method in the Triangle class until the green Run to Click button Run to Click appears on the left. 按钮的工具提示显示“将执行运行到此处”。The tooltip for the button shows "Run execution to here".

    使用“运行时单击”功能Use the Run to Click feature

    备注

    “运行时单击”是 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.

  2. 单击“运行时单击”按钮(运行时单击)。Click the Run to Click button Run to Click.

    使用此按钮类似于设置临时断点。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 the Console.WriteLine method implementation for the Triangle 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

  1. 单击“Drawing a trangle”内并键入校正,将“trangle”更改为“triangle”。Click into "Drawing a trangle" and type a correction, changing "trangle" to "triangle".

  2. 按一次 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.

  1. 按 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 the foreach loop in the Main method.

快速重启应用Restart your app quickly

单击调试工具栏中的“重启”(重启应用)按钮(Ctrl + Shift + F5)。Click the RestartRestart App 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.

  1. shape.Draw() 方法上暂停时,将鼠标悬停在 shape 对象上,你会看到其默认属性值 Rectangle 对象类型。While paused on the shape.Draw() method, hover over the shape object and you see its default property value, which is the object type Rectangle.

  2. 展开 shape 对象以查看其属性,例如 Height 属性,其值为 0。Expand the shape object to see its properties, such as the Height property, which has a value of 0.

  3. 按几次 F10(或选择“调试” > “单步跳过”),在 foreach 循环中重复一次,在 shape.Draw() 上再次暂停。Press F10 (or Debug > Step Over) a few times to iterate once through the foreach loop, pausing again on shape.Draw().

  4. 将鼠标再次悬停在形状对象上,这一次会看到一个类型为 Triangle 的新对象。Hover over the shape object again, and this time you see that you have a new object with a type Triangle.

    查看数据提示View a data tip

    通常情况下,在调试时,需要快速检查变量的属性值,以查看它们是否存储了你希望它们存储的值,可根据数据提示执行此操作。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

  1. 查看代码编辑器底部的“自动”窗口。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.

  2. 展开 shapes 对象。Expand the shapes object.

    在“自动”窗口中检查变量Inspect variables in the Autos Window

    在“自动”窗口中,可看到变量及其当前值。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).

  3. 接下来,我们来看看“自动”窗口旁边的选项卡中的“局部变量”窗口。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

  1. 在主代码编辑器窗口中,右键单击 shapes 对象,然后选择“添加监视”。In the main code editor window, right-click the shapes 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 the shapes 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

  1. foreach 循环中暂停时,单击“调用堆栈”窗口,默认情况下,该窗口在右下方窗格中打开。While paused in the foreach 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.

  2. 单击 F11 几次,直到在代码编辑器中 Triangle 类的 Base.Draw 方法中看到调试器暂停。Click F11 a few times until you see the debugger pause in the Base.Draw method for the Triangle class in the code editor. 查看“调用堆栈”窗口。Look at the Call Stack window.

    检查调用堆栈Examine the call stack

    “调用堆栈”窗口显示方法和函数被调用的顺序。The Call Stack window shows the order in which methods and functions are getting called. 最上面一行显示当前函数(此应用中的 Triangle.Draw 方法)。The top line shows the current function (the Triangle.Draw method in this app). 第二行显示 Triangle.Draw 是从 Main 方法调用的,依此类推。The second line shows that Triangle.Draw was called from the Main 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

  1. Circle.Draw 方法调用中暂停调试器后,使用鼠标抓住左侧的黄色箭头(执行指针),将黄色箭头向上移动一行到 Console.WriteLine 方法调用。With the debugger paused in the Circle.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 the Console.WriteLine method call.

  2. 按下 F11。Press F11.

    调试器将重新运行 Console.WriteLine 方法(你会在控制台窗口输出中看到)。The debugger reruns the Console.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.

  3. 按 F5 继续运行应用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值