NET课件第5部分.ppt
《NET课件第5部分.ppt》由会员分享,可在线阅读,更多相关《NET课件第5部分.ppt(64页珍藏版)》请在冰豆网上搜索。
![NET课件第5部分.ppt](https://file1.bdocx.com/fileroot1/2022-10/7/c7b2bc3c-6527-4f93-a19e-b6543164ecc1/c7b2bc3c-6527-4f93-a19e-b6543164ecc11.gif)
第一部分Microsoft.NET框架基本原理第二部分类型与通用语言运行时第三部分类型设计第四部分基本类型第五部分类型管理,第五部分类型管理异常自动内存管理,第18章异常,18.1异常处理的概念,看以下代码:
classProgramstaticvoidMain(stringargs)intvalues=newint10;for(inti=1;i=10;i+)Console.WriteLine(valuesi);Console.ReadKey();,18.1异常处理的概念,看以下代码:
classProgramstaticvoidMain(stringargs)intvalues=newint10;for(inti=1;i=10;i+)Console.WriteLine(valuesi);Console.ReadKey();,C#中数组下标从0开始,因而此代码在运行时将会发生一个“数组访问越界”错误。
类似于这种在程序中隐藏的错误,被称为“异常(Exception)”,它表明程序执行期间出现了一个非法的运行状况,期望程序进行的某项操作没能完成。
注意,异常是在程序运行时间出现的,不是在编译期间出现的,编译器在编译时发现的错误是语法错误,不能称之为异常。
.NETFramework提供了多个异常类,在编程中常用的有以下几个:
异常处理的目的是根据不同的异常情况提供不同的处置方法,使程序更稳定、更安全。
异常处理的主要用途是提供准确的错误消息,解释失败的原因、位置和错误类型等,同时提供一定的恢复能力,尽可能地降低出错的机率。
使用try、catch和finally处理异常的结构如下:
try/可能引发异常的语句-try语句块
(1)catch(Exceptione)/对异常进行处理的语句-catch语句块
(2)finally/“打扫战场”的语句-finally语句块(3),18.2编程实现异常处理,18.2.1try、catch和finally,异常处理机制将代码分成3大块。
第
(1)块是正常执行程序功能的语句块,其中有可能在运行时引发错误。
第
(2)块在程序正常运行时不会执行,仅当有异常出现时转到此块执行。
第(3)块不管程序执行时有无异常出现都会执行。
当程序正常运行时,程序的执行流程为:
第
(1)块第(3)块当第
(1)块中有代码引发了一个异常时,程序的执行流程为:
第
(1)块第
(2)块第(3)块可以有多个catch语句块,每个代码块捕获一种异常(由catch后的参数类型决定,称为“异常筛选器(ExceptionFilter)”)。
.NETFramework中使用catch语句只能捕获Exception类及其子类的对象。
当一个异常被引发后,如果应用程序没有提供合适的异常处理代码,应用程序进程将会被CLR强制中止。
异常处理机制将代码分成3大块。
第
(1)块是正常执行程序功能的语句块,其中有可能在运行时引发错误。
第
(2)块在程序正常运行时不会执行,仅当有异常出现时转到此块执行。
第(3)块不管程序执行时有无异常出现都会执行。
当程序正常运行时,程序的执行流程为:
第
(1)块第(3)块当第
(1)块中有代码引发了一个异常时,程序的执行流程为:
第
(1)块第
(2)块第(3)块可以有多个catch语句块,每个代码块捕获一种异常(由catch后的参数类型决定,称为“异常筛选器(ExceptionFilter)”)。
.NETFramework中使用catch语句只能捕获Exception类及其子类的对象。
当一个异常被引发后,如果应用程序没有提供合适的异常处理代码,应用程序进程将会被CLR强制中止。
异常处理机制将代码分成3大块。
第
(1)块是正常执行程序功能的语句块,其中有可能在运行时引发错误。
第
(2)块在程序正常运行时不会执行,仅当有异常出现时转到此块执行。
第(3)块不管程序执行时有无异常出现都会执行。
当程序正常运行时,程序的执行流程为:
第
(1)块第(3)块当第
(1)块中有代码引发了一个异常时,程序的执行流程为:
第
(1)块第
(2)块第(3)块可以有多个catch语句块,每个代码块捕获一种异常(由catch后的参数类型决定,称为“异常筛选器(ExceptionFilter)”)。
.NETFramework中使用catch语句只能捕获Exception类及其子类的对象。
当一个异常被引发后,如果应用程序没有提供合适的异常处理代码,应用程序进程将会被CLR强制中止。
注意:
指定由逗号分开的catch参数表是语法错误,catch只能有一个参数,即一条catch语句只能捕获此参数限定的那种类型的异常。
另外,在某个try块后有两个不同的catch块捕获两个相同类型的异常也是语法错误。
finally语句块是可选的,主要用于解决资源泄露问题,它位于catch语句块之后,CLR保证它们一定执行。
注意:
finally语句块中也可能发生异常,如果这种情况发生,先前的异常被放弃。
程序中也可使用throw关键字主动地抛出一个异常:
thrownewException(“我的新异常对象”);,上节中引发“数组访问越界”错误的代码可以用异常处理机制重写如下:
classProgramstaticvoidMain(stringargs)intvalues=newint10;tryfor(inti=1;i=10;i+)Console.WriteLine(valuesi);,catch(IndexOutOfRangeExceptione)Console.WriteLine(“在输出values数组值时发生数组越界错误”);Console.WriteLine(“异常种类:
”+e.GetType().Name);Console.WriteLine(“系统给出的出错信息:
”+e.Message);Console.WriteLine(“系统调用堆栈信息:
”+e.StackTrace);Console.WriteLine(“引发此错误的方法:
”+e.TargetSite);Console.ReadKey();,当程序运行时,异常提示信息如下:
在输出values数组值时发生数组越界错误异常种类:
IndexOutOfRangeException系统给出的出错信息:
索引超出了数组界限系统调用堆栈信息:
在OnlyTest.Program.Main(Stringargs)位置C:
OnlyTestProgram.cs:
行号11引发此错误的方法:
VoidMain(System.String),.NETFramework异常处理的核心是Exception类,它是所有可捕获异常类的基类,程序发生异常时,CLR会创建一个相应种类的异常对象来表示该异常。
Exception对象e的3个重要属性。
.NETFramework实现的异常处理具有以下特点:
处理异常时不用考虑生成异常的语言或处理异常的语言。
异常处,理时不要求任何特定的语言语法,而是允许每种语言定义自己的语法。
允许跨进程甚至跨计算机边界引发异常。
为达以上目的,CLR为每个正在运行的程序创建了一个异常信息表。
在异常信息表中,程序中每个方法都有一个关联的异常处理信息数组。
如果方法中有受到保护的语句块,则此方法相关联的异常处理信息数组中就记录了当异常发生时,CLR自动调用异常处理代码所需的相关信息。
如果某方法中没有受保护块,则其对应的异常处理信息数组为空。
提示:
被trycatch包围的语句块称为受保护块。
18.2.2CLR结构化异常处理原理,当某一方法中发生异常时,CLR在此方法对应的异常处理信息数组中搜索,以确定是哪一个受保护块引发的异常,以及应该由哪个catch块处理。
(1)如果找到以上信息,CLR创建一个Exception对象(或其子类对象)来描述该异常。
然后,CLR执行处理该异常的catch语句块,如果有finally语句块,接着执行finally语句块。
(2)如果在当前方法中没有找到相关信息,则CLR搜索当前方法的每一个调用方,在调用者的异常处理信息数组中搜索,直到最顶层的调用者。
这个由底向上的搜索过程,其信息被记录在一个堆栈中,称为“异常堆栈”。
(3)如果任何调用者都没有处理这种异常的代码,则CLR允许使用一个调试器来处理该异常。
如果用户放弃调试,则CLR引发一个UnhandledException事件,而这时如果应用程序也没有编写响应UnhandledException事件的代码,则CLR会结束此进程。
publicvoidSomeMethod()try/这里执行一些操作catch(NullReferenceExceptione)/处理一个空引用异常catch(InvalidCastExceptione)/处理一个无效转型异常catch/在C#中,该筛选器会捕获任何异常/处理所有异常,首先创建一个自定义的异常类MyException。
classMyException:
ExceptionpublicMyException(Stringinfo):
base(info)接着,编写代码实现以下的方法调用链,在SomeFunc()方法中引发一个Exception异常。
Main()FuncInvoker()SomeFunc()具体代码如下:
异常的传播过程,staticvoidMain(stringargs)FuncInvoker();staticvoidFuncInvoker()SomeFunc();staticvoidSomeFunc()thrownewMyException(“主动引发的异常”);,异常的传播过程,可以在整个异常“传输链”中的任何一环“打断”整个异常传输,以避免进入调试阶段。
修改FuncInvoker函数:
staticvoidFuncInvoker()trySomeFunc();catch(MyExceptione)Console.WriteLine(程序中出现了异常);Console.WriteLine(其信息为:
+e.Message);,如果最底层的SomeFunc()函数引发的不是MyException异常,而是其他类型的异常,则FuncInvoker方法中的trycatch块又不管用了,还是会引发CLR报告错误。
解决方法:
可以在FuncInvoker方法中再增加一个catch语句块,专门处理此种类型的异常。
由于程序中可以引发的异常种类很多,很难一一写代码处理,最保险的方法是在最顶层方法中捕获Exception异常。
staticvoidMain(stringargs)tryFuncInvoker();catch(Exceptione)Console.WriteLine(e.Message);,第19章自动内存管理(垃圾收集),19.1垃圾收集平台基本原理解析,访问一个资源所需要的几个步骤:
1.调用中间语言(IL)中的newobj指令,为表示某个特定资源的类型实例分配一定的内存空间。
2.初始化上一步所得的内存,设置资源的初始状态,从而使其可以为程序所用。
一个类型的实例构造器负责做这样的初始化工作。
3.通过访问类型成员来使用资源,这根据需要会有一些反复。
4.销毁资源状态,执行清理工作。
5.释放内存。
这一步由垃圾收集器全权负责。
以上模式却是导致许多编程错误的主要原因之一。
释放无用的内存、试图访问已经被释放的内存,这两类bug发生的时间和次序都难以预料;这两类bug的直接后果是资源泄露(内存消耗)和对象损毁(状态不稳定)。
正确无误的资源管理通常是一件比较困难和单调的工作,它们极大地分散开发人员解决实际问题的注意力。
垃圾收集(garbagecollection)机制能够简化这种容易遗漏的内存管理任务。
大多数类型表示的资源并不需要任何特殊的清理操作。
对于一个表示(或者说封装)着非托管(操作系统)资源的类