您好,欢迎访问三七文档
第6章调试和错误处理本章要点:非中断模式下的调试中断模式下的调试异常的概念和使用方法异常的处理层次设计和使用异常的处理架构用户自定义异常帐户姓名余额300123张三300124王五47,000311320李四2异常网上银行张三转帐25000到李四的帐面上020,000数据库系统将查询发送到数据库中tranfer_money(){sendquery();}…….…….余额=20000-25000程序崩溃拒绝交易错误系统出现故障6.1正常模式下的调试问题:调试程序对每个程序员来说是家常便饭。可是我们会经常遇到一些情况让我们头疼,例如:•当我们在开发一个界面控件的时候,简单的设断点会增加Paint事件的响应次数,而造成的环境参数改变。•断点设多了,程序常常停在正常运行的地方;这样一来,调试一个错误要花费大量时间去寻找错误。6.1.1输出调试信息System.Diagnostics:该命名空间提供了一些与系统进程、事件日志、和性能计数器进行交互的类库。当中包括了两个对开发人员而言十分有用的类——debug类和trace类。debug类:提供一组帮助调试代码的方法和属性。trace类:提供一组帮助跟踪代码执行的方法和属性。通俗的说就是为在不打断程序的调试或跟踪下,用来记录程序执行的过程。答案:可以将我们所关心的信息输出到另一个位置——IDE中的Output窗口6.1正常模式下的调试区别:Debug类中所有函数的调用都不会在Release版本里有效,Debug只在debug状态下会输出。Trace类能在Release版本和Debug版本中都有效,Trace在Release下也会输出。Debug模式下生成的程序集为调试版本,未经优化;在bin\debug\目录中有两个文件,除了要生成的.exe或.dll文件外,还有个.pdb文件,这个.pdb文件中就记录了代码中的断点等调试信息;Release模式下不包含调试信息,并对代码进行了优化,\bin\release\目录下只有一个.exe或.dll文件。在项目文件夹下除了bin外,还有个obj目录。编译是分模块编译的,每个模块的编译结果就保存在了obj目录下。最后会合并为一个exe或者dll文件保存到bin之中。因为每次编译都是增量编译,也就是只重新编译改变了的模块,所以这个obj的目录的作用就是保存这些小块的编译结果,加快编译速度。6.1正常模式下的调试应用:(1)Debug.WriteLine(Stringmessage)和Trace.WriteLine(Stringmessage)将我们所关心的信息打印在VisualStudioIDE的Output窗口中。String—输出的信息;message—输出文本类别;如果应用程序的不同地方输出了类似的消息,我们就可以马上确定Output窗口中显示的是哪些输出信息例:Debug.WriteLine(“Added1toI”,”MyFunc”);输出:MyFunc:Added1toI(2)Debug.Write(Stringmessage)和Trace.Write(Stringmessage)和WriteLine的区别是Write是不添加行尾字符的输出例:Debug.Write(“Added1toI”,”MyFunc”);Debug.Write(“Write1toI”,”MyFunc1”);输出:MyFunc:Added1toIMyFunc1:Write1toI6.1正常模式下的调试应用:(3)Debug.WriteLineIf(bool参数Stringmessage)和Trace.WriteLineIf(bool参数Stringmessage)区别在于它增加了一个必选参数,且该参数在列表参数的最前面,类型为bool类型,只有这个参数的值为true时,才会输出文本信息(4)Debug.WriteLineIf(bool参数Stringmessage)和Trace.WriteLineIf(bool参数Stringmessage)6.1正常模式下的调试6.1.2跟踪点另一种把信息输出到Output窗口中的方法,作用和Debug.WriteLine()相同。6.1.3诊断输出和跟踪点(1)跟踪点与Trace命令作用不同,它不能再Release版本中输出信息;(2)跟踪点不易输出非常复杂的信息字符串;(3)跟踪点可以在需要时快速添加到应用程序中,同时也非常容易删除;(4)跟踪点允许方便地添加额外的信息;(5)跟踪点只可以在VS中使用6.2中断模式下的调试6.2.1进入中断模式(1)暂停应用程序:是进入中断模式最简单的方式,但这并不能更好地控制停止程序运行的位置。(2)断点:源代码中自动进入中断模式的一个标记。(3)判定语句:生成一个判定语句(assertion)时中断。Debug.Assert(bool参数,string,message)和Trace.Assert(bool参数,string,message)bool参数—要计算的条件表达式。如果条件为true,则不发送指定消息,并且不显示消息框。string和message—要输出的消息文本。例:Debug.Assert(myVar10,”myVaris10orgreater.”,”AssertionoccurredinMain().”);(4)抛出异常:抛出一个未处理的异常时选择进入该模式。6.2中断模式下的调试6.2中断模式下的调试6.2.2进入中断模式(1)暂停应用程序:是进入中断模式最简单的方式,但这并不能更好地控制停止程序运行的位置。(2)断点:源代码中自动进入中断模式的一个标记。(3)判定语句:生成一个判定语句(assertion)时中断。Debug.Assert(bool参数,string,message)和Trace.Assert(bool参数,string,message)bool参数—要计算的条件表达式。如果条件为true,则不发送指定消息,并且不显示消息框。string和message—要输出的消息文本。例:Debug.Assert(myVar10,”myVaris10orgreater.”,”AssertionoccurredinMain().”);(4)抛出异常:抛出一个未处理的异常时选择进入该模式。6.2中断模式下的调试6.2.3监视变量的内容Locals,Watch6.2.4单步执行命令StepInto:执行并移动到下一个要执行的语句上F11StepOver:同上,但不进入嵌套的代码块,包括函数F10StepOut:执行到代码块的末尾,在执行完该语句块后,重新进入中断模式SHIFT+F116.2.5Immediate和Command窗口Immediate和Command窗口:可以在运行应用程序的过程中执行命令Immediate窗口:可以执行源代码,计算表达式,执行其他代码Command窗口:可以手动执行VS操作6.2.6CallStack(调用堆栈)窗口6.3异常处理6.3.1异常的概念异常就是程序运行中发生的错误,程序如果发生异常,我们可以进行异常处理。C#采用面向对象的方法来处理异常。在一个方法的运行过程中,如果发生了异常,则这个方法自动生成代表该异常的一个对象,并把它交给系统,系统寻找相应的代码来处理这个异常。生成异常对象并把它交给系统的过程称为抛出异常。系统在方法的调用栈中查找,从生成异常的方法开始回溯,直到找到包含异常处理的方法为止,这个过程称为捕获异常。6.3异常处理在C#中,每个异常类都代表了一种运行错误,类中包含了该错误的信息和处理错误的方法等内容。所有的异常都表现为一个类的实例,这个类为System.Exception。此类是所有异常类的基类,它包含在system命名空间内,该类的对象可以扑获任何类型异常,其它派生类的对象只能扑获相应类类型的异常。属性MessageSourceStackTraceInnerException描述错误的可读文本,可以在创建异常时传递给构造方法,如果没有则将使用默认错误信息。发生异常时调用堆栈的状态,包括错误发生位置的堆栈跟踪、所有调用的方法和源文件中这些调用所在的行号。当前异常的原因导致异常的应用程序或对象名异常类名称简单描述MemberAccessException访问错误:类型成员不能被访问ArgumentException参数错误:方法的参数无效Argumentnullexception参数为空:给方法传递一个不可接受的空参数ArithmeticException数学计算错误:由于数学运算导致的异常,覆盖面广ArrayTypeMismatchException与数组类型不匹配DivideByZeroException被零除FormatException参数的格式不正确IndexOutOfRangeException索引超出范围,小于0或比最后一个元素的索引还大InvalidCastException非法强制转换,在显式转换失败时引发MulticastNotSupportedException不支持的组播:组合两个非空委派失败时引发Notsupportedexception调用的方法在类中没有实现NullReferenceException引用空引用对象时引发OutOfmemoryException无法为新语句分配内存时引发,内存不足OverflowException溢出StackOverflowException栈溢出TypeInitializationException错误的初始化类型:静态构造函数有问题时引发6.3异常处理6.3.2异常的处理方法1C#的异常处理所用到的关键字try—监控可能发生异常的程序块,若块内发生异常,则发送所有可能的异常;catch—捕获匹配的异常,并加以处理的程序块。可以有多个catch子句;finally—为异常提供一个统一的出口,不论try语句块及catch语句块中是否发生了异常,也不论出现任何语句(即使有throw),finally子句都会被执行。finally经常用于对资源做清理工作如关闭文件等,finally中不允许出现return。throw—引发异常(抛出异常),可引发系统预定义的异常类类型异常和自定义异常类类型异常。6.3异常处理Try...Catch...Finally6.3异常处理1.throw语句【例】usingSystem;publicclassTest{publicstaticvoidMain(){strings1=null;if(s1==null){throw(newArgumentNullException());}}}throw语句一般放在if语句中,只有当条件得到满足(用户自己定义的错误发生)才执行.异常必须是Exception及其子类.6.3异常处理2.try…catch…finally语句(1)程序流进入try块(2)如果没有错误发生,就会正常执行操作。当程序流离开try块后,即使什么也没有发生,也会自动进入finally块(第5步)。但如果在try块中程序流检测到一个错误,程序流就会跳转到catch块(第3步)。(3)在catch块中处理错误。(4)在catch块执行完后,程序流会自动进入finally块。(5)执行finally块【例6.2】6.3异常处理try…catch…finally异常处理格式:try{可能出现异常的程式代码块;}catch(Exceptione){异常处理程式代码块;}finally{无论是否发生异常,均要执行的代码块;}6.3异常处理3.try…catch…finally语句的几种变体应用(1)可以省略finally块(2)可以省略catch块——此时,语法应不是标识异常,而是一种确保程序流在离开try块后执行fnally块中的代码的方式,如果在try块中有几个出口,这是很有用的。(3)可以提供任意多个catch块,处理不同类型的错误。try后面至少有一个catch或finally。fin
本文标题:第6章 异常处理
链接地址:https://www.777doc.com/doc-3375327 .html