错误处理和调试

Download Report

Transcript 错误处理和调试

Slide 1

第十一章 错误处理和调试
本章学习目标:
通过学习主要错误类型来识别程序中可能存
在的错误。学会利用Visual Basic.NET的内置于开发
环境的专业调试器进行程序的调试和错误处理。学习
VB.NET中一些可用的调试功能,例如:如何在代码中
设置断点,在任何指定的点上中止执行,如何监视变
量值的变化等。所有这些都能帮助我们了解代码运行
的情况,更好地进行程序地设计。


Slide 2

第十一章 错误处理和调试
本章学习要点:
(1)主要错误类型的辨认并能纠正错误。
(2) 使用结构化的错误处理。
(3) 利用断点来调试程序。
(4) 利用局部和监视窗口来查看并改变变量和表达
式的值。
(5) 利用即时窗口查询和设置变量。


Slide 3

第十一章 错误处理和调试
不管代码编写得有多好,总是会有一些意外情况
地发生,从而导致代码运行的失败。如果没有预见并
处理这些异常,系统就会给出默认的错误消息,说明
出现了一个未处理的异常(由CLR 提供)。通常默认的
错误消息不能很清楚地通知用户发生了什么情况或如
何纠正错误,未处理的错误还会使用户丢失他们正在
处理的数据,或使用户的数据处于未知状态。
VB.NET提供了错误处理功能,这些功能允许检测
代码,并捕捉可能发生的错误。如果确实发生了一个
错误,可以编写用户容易理解的消息,通知用户发生
了什么异常情况以及怎样纠正它;还可以控制代码的
执行,允许用户再次执行这步操作等。


Slide 4

第十一章 错误处理和调试
调试是任何开发项目中一个必不可少的部分,利
用调试功能也可以找到代码和逻辑中的错误。VB.NET
有一个内置于开发环境的专业调试器。本章学习
VB.NET中一些可用的调试功能,并演示调试程序的过
程。还将讨论如何在代码中设置断点,在任何指定的
点上中止执行,如何监视变量值的变化等。所有这些
都能帮助我们了解代码运行的情况,更好地进行程序
的设计。


Slide 5

11.1 错误类型及处理
11.1.1错误类型
如果知道发生的是何种类型的错误,以及如何纠正它们,会大大加快程
序开发的进程。错误类型主要分为3 种:语法错误、执行错误和逻辑错误。
1.语法错误
“语法错误”是编写代码时出现的错误。在“代码编辑器”窗口中输入
代码时,VB.NET会对其进行检查并在出现错误(如拼错单词或者不正确地使
用语言元素)时提醒用户。语法错误是最普通类型的错误,这类错误一发生,
就可以在代码环境中很容易地修复它们。VB.NET的开发环境有一个相当复杂
的语法检查机制,它对变量和对象提供了即时的语法检查,可以在出现语法
错误时立刻让用户知道这一点。
例如:当用户试图使用未经声明的变量或对象时,开发环境会在该变量
或对象名称的下面加上下划线。这就提示用户产生了一个语法错误。如果将
光标放在这个语法错误上,开发环境就会显示出提示说明这个错误,如图
11.1 所示。


Slide 6

11.1 错误类型及处理

图11.1 使用未声明的hBrush变量或对象的语法错误
Option Explicit 语句是避免语法错误的一种方式。它强制用户事
先声明所有将用于应用程序的变量。因此,当这些变量用于代码时,任
何形式的错误都将被立即捕获并修复。如果使用 Option Explicit语句,
则必须放在文件中任何其他源代码语句之前,所有变量必须使用 Dim
或 ReDim 语句显式声明。


Slide 7

11.1 错误类型及处理
也可以在 VB 集成开发环境 (IDE) 中设置 Option
Explicit,方法是:“工具”菜单->“选项”->“项目和解决
方案”节点->“VB 默认值”->修改“Option Explicit”设置。
如果取默认值:0n(开启)时,VB.NET会强迫在使用变量之前
先声明它们,这样编译器会捕获拼写错误的变量名并提供如
图11.1 所示的帮助。如果取关闭(off)时,所有未显式声明
的变量都假定为Object 数据类型。Object数据类型可以保存
任何类型的值(例如数字或字符串),但与其他数据类型相比,
Object 数据类型的值处理起来要慢一些。所以最好取默认值,
开启Option Explicit 选项。
开发环境还提供了 IntelliSense ,以防止出现语法错
误。IntelliSense 提供了许多功能,比如给类、结构及命名
空间提供了成员的下拉列表,如图11.2 所示。它允许为正在
处理的类、结构或命名空间选择正确的成员。


Slide 8

11.1 错误类型及处理
这样不用记住类所有的可用成员,只需滚动列表就能找
到要处理的项。要从列表中选择要处理的成员,只需按Tab
键、Enter 键,或者双击该成员即可。另外,由于不用输入
成员名称,不会产生拼写错误,所以也不会输入给定类中不
存在的成员名称,从而有效防止了语法错误。

图11.2 IntelliSense下拉列表


Slide 9

11.1 错误类型及处理
IntelliSense另一个强大的功能是它为当前处理的方法提供了一个参
数列表。IntelliSense会列出函数所需要的参数序号、名称和类型,如图
11.3 所示。因为不用记住所处理的每个类的必选参数,可以节省时间提高
效率。

图11.3 IntelliSense的功能


Slide 10

11.1 错误类型及处理
如果方法是重载的,即几个方法有相同的名称,但参
数不同,这个弹出的窗口还可以查看不同的选项,图11.4
显示了FillRectangles方法的不同重载形式。

图11.4 FillRectangles 方法的不同重载形式
在开发环境中,有许多内置功能可以防止语法错误。用户只
需了解这些功能,就可以利用它们来防止代码出现语法错误。


Slide 11

11.1 错误类型及处理
2.运行错误
“运行错误”是仅在编译并运行代码后出现的错误,其中包括可能看
上去正确(因为代码中没有语法错误)但不会执行的代码。它常常是因为
应用程序外部的事物,如用户、数据库或硬盘,没有按照期望的那样执行
而发生的错误。开发人员需要预计发生执行错误的可能性,并建立相应的
代码处理逻辑。进行合适的错误处理并不能防止执行错误,但通过适度地
关闭应用程序或绕过失败的代码,可以给用户一个再次执行该代码的机会。
例如,可能正确地写了一行打开某个文件的代码。但是,如果该文件损坏,
应用程序将无法执行 Open 函数,程序会停止运行。通过重写有错误的代
码,然后重新编译并重新运行该代码,可以修复大多数运行时错误。
防止执行错误的最好办法是在错误发生之前先预计可能出现的错误,
并用错误处理技术捕捉和处理错误。还应该在设计代码之前彻底检测一番。
在开发环境中检测代码时,能够发现大多数的执行错误。这就可以在处理
错误的同时调试代码。然后确定可能发生的


Slide 12

11.1 错误类型及处理
错误类型,并实现合适的错误处理逻辑。利用调试技术可以找到并处
理可能突然发生的任何执行错误。
3.逻辑错误
“逻辑错误”是只要使用应用程序就会出现的错误。通常,当响应用
户操作时,最不希望出现这样的结果。例如,错误输入的值或其他外部影
响可能会导致应用程序在所需的参数内停止运行。逻辑错误通常是最难修
复的错误类型,因为它们发生的位置一般都不明确。
例1:常见的一类逻辑错误是死循环:
Private Sub PerformLoop Example ( )
Do while n<10
‘some logic here
Loop
End Sub


Slide 13

11.1 错误类型及处理
如果循环中的代码永远也不把n 设置为10 或10 以上的数
字,该循环就会永远执行下去,这就发生了逻辑错误。
例2:另一类逻辑错误是比较失败时给出了我们不期望的结
果。
例如一个字符串和一个数据库字段或文件中的文本比较,
而文本是用户输入的。我们不希望进行区分大小写的比较,因
此编写下面的代码:
If filename=userlnput.Text Then
…perform some logic
End If


Slide 14

11.1 错误类型及处理
但是,如果fileName 设置为Index.HTML ,
userInput.Text 设置为index.html , 比较就会失败。为了避
免出现由于大小写而出现的错误,我们把比较的两个字符串都
转换为大写字母或小写字母。这样,如果用户输入了与变量中
的内容相同的文本,即使大小写形式不同,比较的结果也是
true 。下面的代码说明了如何纠正这个错误:
If filename.ToUpper=userInput.Text.ToUpper Then
… perform some logic
End If
因为逻辑错误是最难纠正的错误,所以在编码时必须仔细
检查逻辑,并预计用户可能碰到的所有可能错误。查找和纠正
逻辑错误可以使用VB.NET的调试功能。利用这些功能可以找出
循环执行了过多的次数,或比较有没有得出期望的结果等错误。


Slide 15

11.1 错误类型及处理
11.1.2 错误处理
VB.NET支持“结构化”和“非结构化”错误处理。通过规
划潜在的错误并在应用程序中放置错误处理代码,可以处理用
户可能遇到的大多数错误,防止它们影响应用程序并使应用程
序继续运行。单个处理方法可以包含结构化或非结构化错误处
理,但不能同时包含二者。
一、结构化错误处理
结构化错误处理是以结构化的方式组织错误的处理,而无
需任何GOTO 语句,也不会出现繁琐的代码。结构化错误处理
是通过将控制结构(类似于 Select Case 或 While)与错误、
受保护的代码块和过滤器结合起来实现的,在执行期间检测和
响应错误的代码。VB.NET支持创建具有可靠、全面的错误处理
程序。


Slide 16

11.1 错误类型及处理
VB.NET中的结构化的错误处理是用Try… Catch …
Finally块来处理的。可以在Try块中执行可能引起错误的代码,
在Catch 块中处理预料到的错误。Finally 块是必须执行的,
其中可以放置任何清除代码,而不管错误是否已经发生。如果
发生了一个没有在Catch 块中处理的错误,CLR 就会显示出它
的标准错误消息并终止程序。所以,把代码可能出现的所有错
误都放在Try块中是很重要的。
使用 Try...Catch...Finally 语句,可以保护可能引发错
误的代码块。可以嵌套错误处理程序。在每个块内声明的变量
只在局部范围有效。


Slide 17

11.1 错误类型及处理
1、Try...Catch...Finally 语句
以下代码显示了 Try...Catch...Finally 语句的结构。
Try
[ tryStatements ]
[ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
[ catchStatements ]
[ Exit Try ] ]
[ Catch ... ]
[ Finally
[ finallyStatements ] ]
End Try


Slide 18

11.1 错误类型及处理
各部分说明:
tryStatements:可选。用来指定可能发生错误的语
句。可以是复合语句。
Catch :可选。允许使用多个 Catch 块。如果在处
理 Try 块时发生错误,则会按文本顺序检查每个
Catch 语句,以确定它们是否处理错误,
exception 代表所引发的错误。
exception :可选。可以是任何变量名称。
exception 的初始值是引发错误的值。它将与
Catch 一起使用以指定所捕获的错误。


Slide 19

11.1 错误类型及处理
Type:可选。指定类过滤器的类型。如果没有提供这
个参数,Catch 语句就会处理在system .
Exception 类中定义的错误。利用这个参数可以指
定所要查找的错误类型,比如IOException是对文
件执行任何一种IO(输入/输出)时都会用到的错误。
When:可选。带有 When 子句的 Catch 语句只会在
expression 的计算结果为 True 时捕获错误。
When子句仅在检查错误类型之后应用,expression
可以引用表示错误的标识符。
expression:可选。描述一个通用过滤器的任意表达
式,这个过滤器通常用以过滤指定的错误编号。表
达式必须返回一个布尔值,只有当值为True时才会
处理这个错误。这在过滤错误,以处理指定错误时
非常有用。它与 When 关键字一同使用,以指定捕
获错误时的环境。


Slide 20

11.1 错误类型及处理
catchStatements:可选。用于处理已发生错误的语句
Exit Try可选。用于退出错误处理结构,并继续执行End Try
语句后面的代码。Finally语句仍将被执行,该项不允许在
Finally 块中使用。
Finally:可选。当执行过程离开 Try 语句的任何部分时,总
是会执行 Finally 块。
finallyStatements:是在其他错误处理完成后所执行的语句。
End Try:终止错误处理结构。


Slide 21

11.1 错误类型及处理
在上述的错误处理程序中, Try 块包含监视错误的代码
段。如果在执行该代码段时发生错误,VB.NET检查每个 Catch
语句,直到找到条件与该错误匹配的语句。如果找到这样的语
句,则控制转移到 Catch 块中的第一个代码行。如果没有找
到匹配的 Catch 语句,则继续搜索包含发生错误的块的外部
的 Catch 语句。此过程继续,直到在当前过程中找到匹配的
Catch 块。如果找不到任何匹配,将产生错误。Finally 段中
的代码总是最后执行,并且刚好在超出错误处理块的范围之前
执行。不论 Catch 块内的代码是否已执行,都将清理代码
(如用于关闭文件和释放对象的代码)放在 Finally 段中。


Slide 22

11.1 错误类型及处理
示。

2、Catch 块中的错误过滤
Catch 块允许三个用于特定错误过滤的选择。
(1) 错误的类过滤(本例中为 ClassLoadException),如以下代码所
Try

码。

…………
Catch e as ClassLoadException
…………
Finally
…………
End Try
如果发生 ClassLoadException 错误,则执行指定的 Catch 块内的代


Slide 23

11.1 错误类型及处理
(2) 任何条件表达式的过滤。这种类型过滤器的一个常见用途
是测试特定的错误号,如以下代码所示。
Try
…………
Catch When ErrNum = 5
'指出错误类型
…………
Finally
…………
End Try
当VB.NET找到匹配的错误处理程序后,它执行该处理程序内的
代码,然后将控制传递到 Finally 块。


Slide 24

11.1 错误类型及处理
(3) 将上述两种方法结合起来,同时用于错误处理,这样
Catch 语句从处理最特定的错误变为处理最一般的错误。
3、从 Try…Catch 块中分支
从 Catch 块中分支回最初的 Try 语句或 End Try 语句
是可能的,但不可以分支到封闭的 Try…Catch 块中。如图
11.5所示:
4、结构化错误处理程序
下面的示例显示了一个基于 Try...Catch...Finally 语
句的简单错误处理程序:


Slide 25

11.1 错误类型及处理

图11.5 Try…Catch 块中分支


Slide 26

11.1 错误类型及处理
Public Sub TryExample()
Dim x As Double = 5
' 声明变量
Dim y As Integer = 0
Try
的结构
x /= y

Catch ex As Exception When y = 0
MsgBox(ex.ToString)
Finally
Beep()
End Try
End Sub

'建立错误处理
'引起除数为0错
'引起的错误
'给出错误提示
'执行响铃


Slide 27

11.1 错误类型及处理
Try 块包含可能发生错误的代码,而 Catch 块包含处理
任何错误的代码。如果 Try 块中发生错误,程序控制权将传
递给相应的 Catch 语句进行处理。exception 参数是
Exception 类的实例,或是从对应于 Try 块中所发生错误的
Exception 类中派生的某个类的实例。Exception 类实例含有
关于错误的信息,其中包括错误号和错误消息。
说明:
(1) Try 块中的局部变量将无法在 Catch 块中使用,因
为它们是独立的块。如果要在多个块中使用某个变量,要在
Try...Catch...Finally 结构之外声明该变量。


Slide 28

11.1 错误类型及处理
(2) 如果 Try 语句不包含一个 Catch 块,则必须包含
Finally 块。
(3) 可以使用多个Catch 块,利用多个Catch 块和同一个
Try块可以检测多个错误。在trystatements 中发生一个错误
时,控制就会传递给相应的catchstatements进行处理
(4) 当定义Catch 块时,可以为错误指定一个变量名,并
定义要捕捉的错误类型,如上例的ex错误变量,变量的类型定
义为Exception。
(5) 不论 Catch块中执行什么操作, Finally块始终运行。


Slide 29

11.1 错误类型及处理
二、非结构化错误处理
On Error 语句专门用于非结构化异常处理。在
非结构化异常处理中,On Error 被放置在代码块
的开始处。它具有该块的“管辖范围”,它处理发
生在该块内的任何错误。如果在On Error 语句后
的过程中引发了错误,程序分支转到 On Error 语
句中指定的行。行参数(行号或行标签)指示错误
处理程序的位置。
有时从原始过程调用另一个过程,并且被调用
过程中发生错误,这种情况下,如果被调用过程不
处理错误,则错误传播回调用过程,并且执行分支
到行参数。如果程序遇到另一个 On Error 语句,
则该语句变为有效,而前一个语句变成无效。


Slide 30

11.1 错误类型及处理
1、On Error GoTo Line
On Error GoTo Line 语句假定错误处理代码从所需的
line 参数中指定的行开始。如果运行时发生错误,则控制
转到该参数中指定的行号和行标签,并激活错误处理程序。
指定的行必须和 On Error GoTo Line 语句在同一个过程
中。否则,VB.NET将生成编译器错误。


Slide 31

11.1 错误类型及处理
下面的示例解释了带有行标签的错误处理程序的使用:
Sub TestSub
On Error GoTo ErrorHandler
…………
Exit Sub
ErrorHandler:
…………
Resume
End Sub


Slide 32

11.1 错误类型及处理
该示例包含一个名为 ErrorHandler 的错误处理
程序。如果 TestSub 子程序中的任何代码生成错误,
VB.NET立即执行 ErrorHandler 标签后面的代码。在
错误处理程序的结尾处,Resume 语句将控制传递回
最先发生错误的代码行。然后,该子程序的剩余部分
继续执行,就像没有发生错误一样。
注意: 必须将 Exit Sub 语句紧接着错误处理
块的前面放置。否则,VB.NET在到达子程序的结尾时
将运行错误处理代码,从而导致不需要的或意外的结
果。


Slide 33

11.1 错误类型及处理
2、On Error Resume Next
On Error Resume Next 语句指定如果发生运行错误,控
制传递到紧接在发生错误的语句后面的语句上,从那个位置继
续执行。该语句可以将错误处理程序放在将发生错误的位置,
而不是将控制转移到过程中的另一个位置。
Resume 也可以在 On Error 语句的外部单独使用。当这
样使用 Resume 时,VB.NET将控制返回给导致错误的语句。一
般在错误处理程序改正错误后使用 Resume 语句。
VB.NET还提供了 Resume Next 语句,该语句将控制定向
到紧跟在导致错误的代码行后面的行。可以将 Resume Next
用于错误不会导致应用程序停止运行的情况。如果错误不会更
改子程序的预期结果,也可以使用该语句。


Slide 34

11.1 错误类型及处理
Resume 语句的另一个变化形式是 Resume Line,它类似
于 On Error GoTo Line。Resume Line 将控制传递到 line
参数中指定的行,只能在错误处理程序内使用 Resume Line。
说明:
(1) 如果用户的过程调用另一个过程,在执行被调用的过
程期间,On Error Resume Next 语句变为非活动状态。因此,
应将 On Error Resume Next 语句放在每个需要它的被调用过
程中。因为 Resume Next 语句仅适用于包含 On Error
Resume Next 语句的过程,如果被调用过程中发生未处理的错
误,则错误传播回调用过程,而执行在此调用后面的语句上继
续。这种情况下不处理错误。


Slide 35

11.1 错误类型及处理
(2) 调试代码时,必须禁用 On Error Resume
Next 语句。
3、On Error GoTo 0 / -1
On Error GoTo 0 语句禁用当前过程中的任何错
误处理程序。如果不包括 On Error GoTo 0 语句,
当包含错误处理程序的过程结束时,错误处理程序仍
然被禁用。
注意:不能使用 On Error GoTo 0/-1 语句将行
0/-1 指定为错误处理程序代码的开始,即使过程包
含编号为 0 的行也不行。


Slide 36

11.1 错误类型及处理
4、非结构化错误处理程序示例
在以下代码中,错误处理程序被命名为 DivideByZero 并
处理特定的错误(即尝试被 0 除)。如果发生另外的错误,
VB.NET将引发运行时错误并终止应用程序。
Sub ErrorTest ()
Dim x As Integer, y As Integer, z As Integer
’声明变量
On Error GoTo DivideByZero ’错误处理程序名称"DivideByZero"
x = 2
’引起错误的代码
y = 0
z = x / y
On Error GoTo 0
’禁用当前过程中的任何错误处理
程序
Console.WriteLine(x & "/" & y & " = " & z)
’未作错误处理就退出,会出现意
想不到的结果
Exit Sub


Slide 37

11.1 错误类型及处理
’这个程序演示了处理"DivideByZero"错误
DivideByZero:
Console.WriteLine("You have attempted to divide by
zero!")
’提示信息
y = 2
’给出错误的一个处理办法,令y不为0
Resume
’返回到错误第一次出现的地方继续运行
End Sub
三、结构化与非结构化错误处理的选择
简单地说,结构化错误处理是指使用包含错误的控制结构、隔离
的代码块和过滤器来创建错误处理机制。这样,在代码中就可以区分不同
类型的错误,并根据环境做出相应的响应。在非结构化错误处理中,位于
代码开头的 On Error 语句处理所有的错误。


Slide 38

11.1 错误类型及处理
与非结构化错误处理相比,结构化错误处理的适
用面更广、更可靠,并且更灵活。应尽可能地使用结
构化错误处理。在同一函数内,不能混用结构化和非
结构化错误处理。如果使用 On Error 语句,则在同
一函数中不能使用 Try...Catch 语句。
无论用户选择哪种机制来处理代码内的错误,都
必须退一步考虑该代码有哪些假设。例如,如果用户
的应用程序要求用户输入电话号码,则有以下假设:
用户将输入一个数字,而不是字符。
该数字有特定的格式。
用户不会输入空字符串。
用户只有一个电话号码。


Slide 39

11.1 错误类型及处理
用户的输入可能会违反这些假设中的任何
一个或全部。可靠的代码需要足够的错误处理
机制,使应用程序在用户的输入违反这些假设
时能够正常恢复。
除非可以确保程序在任何情况下都不会引
发错误,否则应考虑使用说明性错误处理。错
误处理应该是有意义的,除了指出有错误发生
外,错误处理产生的信息还应说明发生错误的
原因和位置。如果提供的信息不具有说明性,
而仅仅指出“发生错误”,只会使用户感到更
迷惑。


Slide 40

11.2 调试

11.2.1调试设置
调试代码是程序设计必不可少的一部分,下面介绍
一下VB.NET开发环境中一些内置的调试功能。VB.NET
调试器是一个功能强大的工具,利用它可以观察程序
的运行并确定逻辑错误的位置。使用调试器,可以中
断(或挂起)程序的执行以检查代码,计算和编辑程
序中的变量,查看寄存器,查看从源代码创建的指令,
以及查看应用程序所占用的内存空间。还可以在调试
时对代码进行更改,然后继续执行。
VB.NET调试器提供了一个用于访问调试器工具的
“调试”菜单。如图11.6所示。调试器的窗口和对话
框显示有关用户程序的信息,并允许用户输入附加的
信息。可以通过按 F1 获得关于任何窗口或对话框的
帮助。


Slide 41

11.2 调试
还可以利用调试工具栏来实现各种调试功能,在设计窗
口显示调试工具栏方法是:“视图”->”工具栏”->”调试”。
调试工具栏上显示了一些有用的图标,如图11.7 所示。

图11.6 调试菜单

图11.7

D


Slide 42

11.2 调试
调试图标可以根据需要增加或减少,方法是:
打开“工具”菜单->选择“自定义”->在类别中选
择“调试”项->在命令窗口选择要添加的命令,拖动到工
具栏上的,所选的命令就会在工具栏上显示。图11.8显
示了打开的自定义窗口,选择“运行到光标处”的窗口
内容。


Slide 43

11.2 调试

图11.8显示了打开的自定义窗口


Slide 44

11.2 调试
常用的几个调试图标如图
11.9所示,
分别是:逐语句/逐过程/跳
出/运行到光标处。
11.9
常用的调试图标
第1个图标是逐语句图标,单击该图标,可以对调用的任
何函数或过程内的代码进行单步调试。
第2个图标是逐过程图标,它的工作方式与逐语句图标相
似,但会跳过被调用过程或函数中的代码,一次执行被调用
过程或函数后继续执行调用程序的下一行代码。
第3个图标是跳出图标。这个图标允许跳到当前过程或函
数的最后,执行调用该过程或函数的下一行代码。当单步执
行到一个很长的过程中,想退出该过程时可以使用该图标,
过程中的其余代码依然会执行,但不需要单步调试它们。


Slide 45

11.2 调试
第4个图标是运行到光标处。将光标放在当前断点之后或任何想暂停程
序执行的地方,然后单击该图标,就会执行当前断点和光标所在位置之间的
代码,而到了光标所定位的那行代码,执行就会停止。
以下我们依次介绍一些调试器及调试菜单的一些功能。
一、还原隐藏的调试器命令
安装VB.NET时,系统会要求用户选择一组默认的 IDE 设置。如果使用
由默认 IDE 设置隐藏的调试器功能,可以使用以下步骤将相应的命令重新
添加到菜单中。
(1) 在项目处于打开的状态下,在“工具”菜单上单击“自定义”。
(2) 在“自定义”对话框中,单击“命令”选项卡。
(3) 在“类别”框中,选择“调试”。
(4) 在“命令”框中,选择要添加的命令,并将其拖动到“调试”菜单。
(5) 重复上面的步骤来添加其他命令。
(6) 完成将命令添加到菜单后,单击“关闭”。


Slide 46

11.2 调试

某些菜单项仅在调试器处于特定模式(如运行模式或中断模
式)下才显示。因此,在完成这些步骤后,用户所添加的项可
能不会立即显示出来。
二、开始调试
开始调试是最基本的调试功能之一。使用调试器控制应用程
序的执行包括以下操作:开始(或继续)执行、中断执行、停
止执行、逐句通过应用程序、运行到指定位置以及设置执行点
等。
1.开始调试
可以从“调试”菜单中选择“启动调试”、“逐语句”或
“逐过程”。也可以在源窗口中,右击可执行代码中的某行,
然后从快捷菜单中选择“运行到光标处”来执行开始调试的功
能。
如果选择“启动调试”,则应用程序启动并一直运行到断点。
可以在任何时刻中断执行,以检查值、修改变量或检查程序状态。
如果选择了“逐语句”或“逐过程”,应用程序启动并执行,
然后在第一行中断。


Slide 47

11.2 调试
如果选择“运行到光标处”,则应用程序启动并一直运行到
断点或光标位置,具体看是断点在前还是光标在前。可以在源
窗口中设置光标位置。有些情况下,不出现中断意味着执行始
终未到达设置光标处的代码。
2.中断执行
当用VB.NET调试器调试应用程序时,应用程序或正在运行或处于中断模
式。大多数调试器功能(比如在“监视”窗口中计算表达式)只在中断模式
下可用。
当执行到达一个断点或发生错误时,调试器将中断程序的执行。也可以
随时手动中断执行,方法是:在“调试”菜单上,单击“全部中断”。
中断发生时,调试器将停止所有在调试器下运行的程序的执行。程序并
不退出,可以随时恢复执行。如果正在调试多个程序,则默认情况下,断点
或“全部中断”命令将影响所有被调试的程序。如果想仅中断当前程序,可
以更改该默认值。
更改调试多个程序时的中断操作用如下方式:


Slide 48

11.2 调试
(1) 在“工具”菜单上,单击“选项”。
(2) 在“选项”对话框中,选择“调试”文件夹,并单击“常规”类
别。
(3) 切换“一个进程中断时则中断所有进程”。
(4) 单击“确定”。
3.停止调试或停止执行
停止调试意味着终止调试过程。停止执行意味着终止正调试的进程并
结束调试过程。不要与中断执行混淆,中断执行意味着暂停正在调试的进
程的执行但调试过程仍处于活动状态。
停止调试的方法是:从“调试”菜单中选择“停止调试”。


Slide 49

11.2 调试
4.代码单步执行
单步执行是最常见的调试过程之一,即每次执行一行代码。“调试”
菜单提供了三个逐句执行代码的命令:
 逐语句
 逐过程
 跳出
“逐语句”和“逐过程”的差异仅在于它们处理函数调用的方式不同。
这两个命令都指示调试器执行下一行的代码。如果某一行包含函数调用,
“逐语句”仅执行调用本身,然后在函数内的第一个代码行处停止。而
“逐过程”执行整个函数,然后在函数外的第一行处停止。如果要查看函
数调用的内容,应使用“逐语句”。若要避免单步执行函数,请使用“逐
过程”。在嵌套函数调用上,“逐语句”将进入并单步执行嵌套最深的函
数。如果对类似 Func1(Func2( )) 的调用使用“逐语句”,调试器将进入
并单步执行函数 Func2。


Slide 50

11.2 调试
5.运行到指定位置
在“调试”菜单上,单击“启动调试”或“继续”就可以
运行到已设置断点的指定位置。
在VB.NE调试器中,还可以移动执行点来设置要执行的下一
条代码语句。单击“启动调试”或“继续”后,代码窗口空白
区域中的黄色箭头标记要执行的下一条语句的位置。通过移动
此箭头,可以跳过部分代码或返回到以前执行过的行。在某些
情况下可以使用此方法,例如,跳过包含已知 bug 的代码段
等。在代码窗口中,右击要执行的下一条语句,然后从快捷菜
单中选择“设置下一语句”,也可以设定指定位置。


Slide 51

11.2 调试
11.2.2 断点设置
为了演示断点的设置,先创建示例项目,编写一个示例程序如下:
例:创建一个用于调试的示例项目,在源代码的顶部添加下列项目代码:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles MyBase.Load
Dim s As Integer
Dim i As Integer
s = 0
i = 1
While i <= 10
s = s + i
i = i + 1
End While
MsgBox("1+2+3+4+5+6+7+8+9+10=" & s)
End Sub


Slide 52

11.2 调试

图11.10 示例程序的运行的结果
1.什么是“断点”
断点是一个信号,它通知调试器,在某个特定点上
暂时将程序执行挂起。当执行在某个断点处挂起时,我们称程序处
于中断模式。进入中断模式并不会终止或结束程序的执行。执行可
以在任何时候继续。


Slide 53

11.2 调试
断点模式可以看作一种超时,所有元素(例如函数、变量和对象)都
保留在内存中,但它们的执行和活动被挂起了。在中断模式下,许多调试
功能也只有在程序处于中断模式时才能使用,用户可以检查它们的位置和
状态,以查看是否存在冲突或 bug。用户可以在中断模式下对程序进行调
整。例如,可以更改变量的值,可以移动执行点等。在VB.NET中,甚至可
以在中断模式下对代码本身进行更改。
断点提供了一种强大的工具,使用户能够在需要的时间和位置挂起执
行。与逐句或逐条指令地检查代码不同的是,可以让程序一直执行,直到
遇到断点,然后开始调试。这大大地加快了调试过程。没有这个功能,调
试大的程序几乎是不可能的。而且断点不必改动程序源代码就可以删除或
更改,由于断点不是语句,当生成程序的发行版时,它们不会产生额外的
代码。图11.11 显示了代码在执行过程中遇到断点时的情况。


Slide 54

11.2 调试

图11.11 执行过程中遇到断点
图11.12显示了运行到断点处的显示窗口。在开发环境的
底部有几个新窗口,这些窗口的内容取决于用户指定要显示什么
内容,使用底部的选项卡可以选择显示不同的窗口。


Slide 55

11.2 调试

图11.12 运行到断点处的显示窗口


Slide 56

11.2 调试
2.使用“断点”
在调试一个大程序时,常常只需要调试其中的一部分代码。也就是说,
让代码运行到某一处以后停下来,这时就要使用断点。我们可以在代码的
任何地方设置断点,代码就会在设置断点的那行之前停止执行。可以在编
写代码时设置断点,也可以在运行时转换到代码窗口,在所希望的位置设
置断点。当程序正在实际执行一段代码(如循环中的代码)时,就不能设置
断点,但可以在程序空闲,等待用户输入时设置断点。
设置断点时,可以单击要设置断点的代码行旁边的灰边,设置好断点
后,在灰边上会出现一个红色圆点,该代码行以红色突出显示。使用完一
个断点后,单击红色圆点就可以删除它。图11.13 显示了设置断点时的情
况。


Slide 57

11.2 调试

图11.13

设置断点


Slide 58

11.2 调试
设置断点除了可以在代码窗口中单击要设置断点的那行可
执行代码以外,还可以在快捷菜单中,通过转到“断点”,然
后选择“插入断点”,或者从“调试”菜单中选择“切换断点”
实现。
3.断点标志符号
代码窗口左侧空白处显示标志符号,以此来显示断点位置,
表11-1描述了这些标志符号。


Slide 59

表11-1 断点标志符号
标志符号





普通断点。实心的标志符号指示断点已启用。空心的标志符
号指示断点已禁用。

高级断点。活动/禁用。“+”符号指示断点至少有一个附加到
它的高级功能,例如条件、命中次数或过滤器。
跟踪点。活动/禁用。命中此点则执行指定的操作,但不中断
程序的执行。
高级跟踪点。活动/禁用。“+”符号指示断点至少有一个附加
到它的高级功能,例如条件、命中次数或过滤器。
断点错误或跟踪点错误。“X”指示由于出现错误而未能设置
断点或跟踪点。
断点警告或跟踪点警告。感叹号指示由于临时情况而未能设
置断点或跟踪点。通常情况下,这意味着还没有加载断点或
跟踪点位置处的代码。加载代码后,将启用断点,标志符号
也将更改。


Slide 60

11.2 调试
如果将鼠标悬停在断点标志符号上,将显示更多断点的提示信息,此
信息对于错误断点和警告断点来说特别有用。
4.断点窗口
断点窗口为高级用户提供功能强大的操作断点的方法。要显示断点窗
口,可以单击调试工具栏上的断点图标,或者单击“调试| 窗口|断点”菜单
项,断点窗口会显示出当前断点所在的代码行,断点的条件以及相应的访
问计数器,如图11.14 所示。

图11.14 断点窗口


Slide 61

11.2 调试
断点窗口会显示出所设置的所有断点,在本例中只有一个。
在这个窗口中,可以设置新的断点,删除原有的断点,还可以
改变断点的属性从“断点”窗口转到代码窗口。可以使用下面
的方法从“断点”窗口中的断点转到源代码窗口中的对应位置。
右击断点并选择“转到源代码”或单击断点,然后单击“转到
源代码”。此外,在断点窗口还可以进行下列设置:
调整“断点”窗口,使它以需要的方式显示用户要查看的信
息。
显示其他列:在顶部的工具栏中,单击“列”工具并选择
要显示的列名。
加宽或变窄列:单击列分隔符并将其左右拖动。
隐藏列:在顶部的工具栏中,单击“列”工具并选择要隐藏
的列名。
重新排列列的顺序:拖放列标题。
禁用/启用断点:清除或选中断点旁边的复选框。


Slide 62

11.2 调试
5.断点的编辑处理
利用“断点”窗口或者“断点”的快捷菜单可以对断点进行编
辑处理。“断点”窗口的工具栏的功能为:

图11.15 断点窗口的工具栏
对应的功能为:新建/删除/删除所有断点/禁用所有断点/转到
源代码/转到反汇编/列的设置。在代码窗口的断点标志上单击右键,
显示的快捷菜单为图11.16所示:
在“断点“窗口内单击右键,显示的快捷菜单为图11.17所示:


Slide 63

11.2 调试

图11.16断点标志的快捷菜单
图11.17断点窗口内的快捷
菜单
在工具栏或快捷菜单中可以实现下列功能:删除断点、
启用/禁用断点
在图11.16的调试菜单中,可以设置:删除所有断点,
删除断点前,可以设置询问信息,方法是: “工具”菜单->“选
项”->“调试”节点->单击“常规”->“在删除所有断点之前询问”复
选框控制是否显示提示。


Slide 64

11.2 调试
6.断点的命中计数
有时希望调试循环中的代码,比如从文件中读取数据的循环。如果事
先知道循环在前x 个记录中会顺利运行,但以后就不敢保证,那么为了找到
有问题的记录,必须在所有的代码中重复进行单步调试,这就非常耗时。
我们可以通过在循环中设置断点,并给它设置一个访问计数器来避免这种
情况,这样循环中的代码会执行到访问计数器中指定的循环次数后停下来,
并回到中断模式,这样就可以运行节约时间。
命中次数能够确定在调试器中断执行之前命中断点的次数。在默认情
况下,每次命中断点,调试器就中断执行。通过设置命中次数,可以让调
试器每命中任意选择的次数中断一次。如图11.18所示的断点命中次数窗口。


Slide 65

11.2 调试
命中次数项可以选择:
总是中断(默认设置)。
命中次数等于指定值时中断。
命中次数等于指定值的倍数时中断。
命中次数大于或等于指定值时中断。

11.18 断点的命中次数对话框中设置断点的命中次数


Slide 66

11.2 调试
如果要跟踪断点的命中次数但不中断执行,可以将命中次数设置为一个
很高的值以便永不命中断点,仅为调试过程保留指定的命中次数,在调试
过程结束时,命中次数将重置为零。
指定命中次数:
从“命中断点时”列表框中选择所需的行为。
如果选择除“总是中断”以外的任何设置,则列表框旁边将出现一个编
辑框。编辑出现在编辑框中的整数,可以设置所需的命中次数。单击“确
定”。
运行设置了断点的程序后,查看断点窗口如图11.19所示:

图11.19 断点窗口显示命中计数条件,以及当前的命中计数值
(可以和11.14对比一下)


Slide 67

11.2 调试
7.断点设置条件
断点条件是一个第一次到达断点时调试器将计算的表达式。
如果满足条件,则调试器将查看如何指定命中次数,以确定是
否中断(或执行另一个指定的操作)。如图11.20所示:

图11.20 断点的条件设置窗口


Slide 68

11.2 调试
条件可以是调试器可识别的任何有效表达式。如果在设置断点条件时
使用了无效语法,将立即出现警告消息。如果在指定断点条件时使用的语
法有效但语义无效,则在第一次命中断点时会出现警告消息。在这两种情
况下,当命中无效断点时,调试器都会中断执行。只有当条件有效并且条
件的计算结果为 false 时,才会跳过断点。
指定断点条件:
在快捷菜单中选择“条件”。
在“断点条件”对话框的“条件”框中输入有效的表达式。
如果想要在满足表达式时中断,请选择“为真”;如果想要在表达式
的值已更改时中断,请选择“已更改”。


Slide 69

11.3 调试窗口
11.3.1 使用即时窗口进行调试
即时窗口是调试程序时一个非常有用的帮手。利用它可以
通过查询并设置变量的值来控制程序的执行和输出。甚至可以
在即时窗口中编写小段代码来改变程序的输出,比如关闭对象
或改变值。只有在程序处于中断模式时,即时窗口才允许输入
代码,但可以在设计时查看即时窗口的内容。设置即时窗口的
方法是:“选项”对话框 ->“调试”->“实时”。若要访问
“实时”页,请单击“工具”菜单并选择“选项”。在“选项”
对话框中,展开“调试”节点并选择“实时”。如图11.21所
示:


Slide 70

11.3 调试窗口

图11.21设置实时窗



Slide 71

11.3 调试窗口
在代码设计窗口启动即时窗口,单击“调试”菜单->窗口>即时,启动画面为图11.22所示。

图11.22 即时窗口


Slide 72

11.3 调试窗口
当在VB.NET外运行的程序遇到致命错误时,VB.NET自动启
动调试器,不需要在发生错误时是运行的。即时调试使用户能
够在应用程序被操作系统终止之前检查错误。如果在调试器启
用了即时调试的情况下发生了错误,将打开一个对话框,询问
用户是否要调试程序,以及要使用哪个调试器。
即时调试是在VB.NET之外启动程序的一种方法。可以在
VB.NET环境之外运行在VB.NET中创建的程序。如果已启用即时
调试,则发生崩溃时会出现一个对话框询问是否要进行调试。
用户可以使用VB.NET“即时窗口”在没有运行应用程序的
情况下执行函数或子程序。如果函数或子程序包含断点,
VB.NET将在适当的点中断执行。然后用户就可以使用调试器的
窗口检查用户的程序状态,此功能称为设计时调试。例如,在
调试程序时查询程序中变量的值,查询结果就会在即时窗口中
列出。停止执行代码,查看即时窗口可以看到所执行命令的结
果,而且可以对代码进行必要的调整。
下面的过程显示了从“即时”窗口命中断点的情况。


Slide 73

11.3 调试窗口
例如:首先将下列代码粘贴到VB.NET控制台应用程序中:
Module Module1
Sub Main()
End Sub
Function MyFunction() As Decimal
Static i As Integer
i = i + 1
Dim s As String
s = "Add Breakpoint here"
Return 4
End Function
Sub MySub()
MyFunction()
End Sub
End Module


Slide 74

11.3 调试窗口
在 s=“Add BreakPoint Here” 行上设置一个断点。
2.在“即时”窗口中键入以下内容:?MyFunction,如图11.23
所示
3.命中了断点以后, 单击“继续”回到设计模式。如图11.24所示
4.在“即时”窗口中继续键入以下内容:?MyFunction
5.在“即时”窗口中继续键入以下内容:?MySub,如图11.25
所示
6.命中了断点,并在“局部变量”窗口中检查静态变量 i 的值。它的
值应当为 3。如图11.26所示
7.在“调试”菜单上,单击“继续”,并回到设计模式。
在窗口中右击并从弹出的快捷菜单中选择“全部清除”,就可以清除命
令窗口中所有的内容。


Slide 75

11.3 调试窗口

图11.23 在即时窗口输入命令

图11.25 在即时窗口继续输入命令

图11.24

在即时窗口显示运行结

图11.26在局部变量窗口查看i的值


Slide 76

11.3 调试窗口
11.3.2 使用变量窗口
VB.NET调试器提供的变量窗口用于在进行调试时显示变量信
息。每个变量窗口都是网格窗口,包含三列:“名称”、“值”
和“类型”。显示在网格中的信息类型取决于正在使用的变量
窗口。
“名称”列显示在“自动”和“局部变量”窗口中自动添加
的变量的名称。在“监视”窗口中,“名称”列可以添加用户
自己的变量或表达式。
“值”和“类型”列显示相应变量或表达式结果的值和数据
类型。在“值”列中可以编辑变量的值。
在VB.NET中,将光标放在变量上可以快速查看该变量的值。
出现一个显示信息的小框,称为“数据提示”
如果要显示变量窗口,可以从“调试”菜单中选择“窗口”,
然后选择要显示的变量窗口的名称,它们是“自动”、“局部
变量”、“监视”下的监视1 到 监视4。
在设计模式下不能访问这些菜单项,也不能显示这些窗口。
若要显示这些菜单项,调试器必须正在运行或处于中断模式。


Slide 77

11.3 调试窗口
一.监视窗口
监视窗口(Watch Window )提供了一个方法,通过该方法可以方便地在执
行代码时监视变量和表达式的值,这在调试变量的结果时是非常有用的。还
可以在监视窗口中改变变量的值或根据需要添加变量和表达式,以调试程序。
当程序处于中断模式时,只能在快速监视对话框中添加和删除变量或表达式。
因此,在运行程序之前,需要在想监视的变量或表达式之前设置一个断点。
这样,当程序运行到断点时,就可以根据需要添加监视变量或表达式了。
VB.NET有多个“监视”窗口,其编号为监视1到 监视4。监视窗口调试器
提供了很多变量窗口,这些窗口用于显示、计算和编辑变量与表达式。每个
变量窗口都是网格窗口,包含三列:“名称”、“值”和“类型”。
例如:使用监视窗口监视变量值的变化,当监视窗口中变量的值变成红
色时,就表示该值发生了改变。还可以手动改变该值,方法是在监视窗口的
值栏中输入新值。如图11.27的监视窗口。


Slide 78

11.3 调试窗口

图11.27监视窗口
“快速监视”对话框在概念上类似于“监视”窗口,但是“快速监
视”每次只能显示一个变量或表达式。使用“快速监视”对话框在同
一时间可以检查单个变量或单个表达式。它可以用来快速查看一个值
或一个较大的数据结构。而 “监视”窗口可以存储很多变量和表达
式,这些变量和表达式都是要在调试过程中查看的。如果需要快速查
看变量或表达式而不想打开“监视”窗口,则可以使用“快速监视”。
虽然“快速监视”是对话框,但其工作方式很像其他变量窗口。“快
速监视”窗口的


Slide 79

11.3 调试窗口
另一个好处是它是可变大小的。如果要查看一个较大对象
的成员,在“快速监视”窗口中通常比在“监视窗口”、“局
部变量”或“自动窗口”中更方便展开和查看。
“快速监视”对话框不允许一次查看多个变量或表达式。
而且,由于“快速监视”是一个模式对话框,因此无法在“快
速监视”打开时执行其他操作,如逐句执行代码。
打开添加有变量的“快速监视”对话框方法是:在中断模式
下,右击源窗口中的变量名,然后从快捷菜单中选择“快速监
视”。这样,就将变量自动放置到“快速监视”对话框中。
将“快速监视”表达式添加到“监视”窗口只需在“快速
监视”对话框中,单击“添加监视”按钮。 “快速监视”对
话框中显示的任何表达式都会立即添加到“监视”窗口中的表
达式列表中。
如果用户使用的VB.NET版本支持多个“监视”窗口,则表
达式将添加到“监视 1”窗口。如果需要执行下列操作,请改
用“监视”窗口。在“监视”窗口或“快速监视”中进行下列
操作,调试器必须处于中断模式。


Slide 80

11.3 调试窗口
1.输入变量或表达式
网格窗口中,单击“名称”列中的空行。键入或粘贴要监
视的变量名或表达式或者将其拖到“监视”窗口中的某行后
按 Enter。
结果出现在“值”列中。如果键入数组或对象变量的名称,
“名称”列中的名称旁边就会出现树控件。用户可以展开或
折叠“名称”列中的变量。
用户可以输入表达式作为值。调试器将计算表达式,并将
它替换为计算后所得到的值。调试器在“监视”窗口中接收
大多数合法的表达式,表达式一直保留在“监视”窗口中,
直到将其删除为止。


Slide 81

11.3 调试窗口
计算某些表达式可能会更改变量的值,或会影响程序的状态。例如,计
算下列表达式会更改 var1 和 var2 的值:var1 = var2++。更改数据的表
达式被称为有副作用的表达式,如果不知道这种情况,副作用可能会产生
意外的结果。所以,执行表达式之前,一定要了解表达式的作用。
2.更改数字格式
可以把调试器窗口中显示数值的格式设置为十进制或十六进制,方法是:
在调试器窗口中右击,在快捷菜单中,设置或清除“十六进制显示”。此
处选定的数字格式可影响所有的调试器窗口。
3.编辑变量窗口或“快速监视”中的值
可以手动重写变量的值,方法是:
(1)如果变量是数组或对象,则“名称”框中的名称旁边将出现树控
件。在“名称”列中,展开或折叠变量,可以找到要编辑元素。
(2)在要更改的行中,双击“值”列。
(3)键入新值。


Slide 82

11.3 调试窗口
二、局部变量
“局部变量”窗口显示对于当前上下文或范围来说位于本
地的变量。通常,这是当前正在执行的过程或函数,调试器自
动填充此窗口。局部窗口(Local Window )和监视窗口非常相
似,但它显示的是当前函数或过程执行中的所有变量和对象。
局部窗口也可以改变变量或对象的值,其规则与使用监视窗口
的规则是一样的。在改变值之前,必须暂停程序。刚改变的值
的文本会变红,这样就很容易辨认出刚发生改变的变量或对象。
如果想快速浏览一下函数或过程中将要执行的内容,局部
窗口是极为有用的。但是要监视一两个变量或表达式的值,局
部窗口就不是那么有用了。这是因为局部窗口包含了过程或函
数中所有的变量和对象。因此,如果有很多变量和对象,必须
经常滚动窗口以查看不同的变量和对象。这时使用监视窗口会
比较方便,它可以只监视所需的变量。
例:使用局部窗口


Slide 83

11.3 调试窗口
1 首先在前面使用过的为了演示断点的设置而创建的示例项目:求前10
个自然数的和的代码行:While i <= 10 前设置断点。
2 单击调试工具栏上的开始图标,或调试菜单中的开始调试运行该程
序,如果没有在开发环境底部看到局部窗口,可单击“调试|窗口|局部菜单
项”。
3 局部窗口中列出了不同的对象和它们的类型,如图11.28 所示。列表
中的第一项是Me ,这是窗体本身,展开这个项,会看到与窗体相关的所有
对象和控件,如图11.29 所示。
4 单击调试工具栏上的继续图标,则局部窗口中的值就会发生改变,
这和在监视窗口中看到的相同。


Slide 84

11.3 调试窗口

图11.28 局部窗口中列出了不同的对象和它们的类型


Slide 85

11.3 调试窗口

图11.29 展开Me项后的内容窗口


Slide 86

11.3 调试窗口
三、自动窗口
“自动”窗口显示在当前代码行和上一代码行中使用的变
量。与“局部变量”窗口类似,“自动”窗口是由调试器自动
填充的。
11.3.3 其他功能
“编辑并继续”是一种省时的功能,能够在程序处于中断
模式时更改源代码。当用户通过选择一条类似继续或单步执行
的执行命令继续执行程序时,“编辑并继续”有限制地自动应
用代码更改。这允许用户在调试程序期间更改代码,而不是停
止程序,重新编译再重新启动调试过程。
“选项”对话框 “调试”“编辑并继续”可以启动
“编辑并继续”功能。若想显式应用代码更改只需从“调试”
菜单中选择“应用代码更改”。
安装VB.NET时,“编辑并继续”在默认情况下是打开的。
若要启用/禁用“编辑并继续”功能,请执行以下过程:


Slide 87

11.3 调试窗口
1 在“工具”菜单上单击“选项”。
2 在“选项”对话框中,打开“调试”节点并选择“编辑
并继续”类别。
3 若要启用,请选择“启用‘编辑并继续’”复选框。若
要禁用,则清除该复选框。
4 单击“确定”。
可以禁用“编辑并继续”的自动调用(通过“继续”、
“执行”和“单步执行”命令来调用)。如果正在编辑不想应
用于当前调试过程的代码,可能要这样做。也可以重新启用
“编辑并继续”的自动调用。启用或禁用“编辑并继续”的自
动调用的方法是:


Slide 88

11.3 调试窗口
1 在“工具”菜单上单击“选项”。
2 在“选项”对话框中打开“调试”节点,然后
选择“编辑并继续”类别。
3 在“编辑并继续”组中,选择或清除“由调试
命令调用”复选框。
注意:可以在使用调试命令以前,让调试器先进
行询问,然后再应用代码更改。如果希望询问,请选
择“首先询问”复选框。由于“由调试命令调用”是
一个工具选项,因此更改此设置将影响处理的所有项
目。
停止应用代码更改可以从“调试”菜单中选择
“停止应用代码更改”。该菜单项仅在应用代码更改
时才可见。如果选择了该选项,就不会进行任何代码
更改。


Slide 89

本章小结
在本章中讨论了在开发和调试代码时,可能会遇到的错误类
型,辨认语法和执行错误,并纠正它们是很重要的。不过,调
试程序时找到所遇到的逻辑错误可能比较难,这需要时间和经
验。
在本章还讨论了结构化和非结构化的错误处理,应在任何时
候将这部分内容合并到程序设计中去。它不仅可以为用户提供
更容易理解的消息,而且,在调试代码出问题时,还可以提供
帮助和一些要了解的基本信息。例如,关于错误和引起错误的
代码行的精确定位的消息等。
本章还讲述了一些内置于VB.NET开发环境的有用的调试工具。
通过对一些例子的讲解,说明了如何用这些工具调试程序。


Slide 90

本章小结
对断点进行详细讲解后,还讨论了如何在指定点停止程序
的执行。在循环中给断点设置命中计数器很用,因为能够在执
行若干次的循环后暂停程序的执行。
还分析了调试程序时的各种窗口,比如局部窗口和监视窗
口。这些窗口提供了程序中变量和表达式的一些有用信息,我
们能够监视值的改变,甚至能够通过改变值来控制代码的执行。