首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 网络编程-> ASP教程
异常和错误处理(基于delphi/vcl)_delphi教程
作者:网友供稿 点击:0
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
   有人在看了我的“如何将界面代码和功能代码分离(基于Delphi/VCL)”之后,提到一个问题,就是如何对服务端的类的错误进行处理。
    在基于函数的结构中,我们一般使用函数返回值来标明函数是否成功执行,并给出错误类型等信息。于是就会有如下形式的代码:
    RetVal := SomeFunctionToOpenFile();

    if RetVal = E_SUCCESSED then
        ......
    else if RetVal = E_FILENOTFOUND then
        ......
    else if RetVal = E_FILEFORMATERR then
        ......
    else then
        ......
    使用返回错误代码的方法是非常普遍的,但是使用这样的方法存在2个问题:
    1、造成冗长、繁杂的分支结构(大量的if或case语句),使得控制流程变得复杂
    2、可能会有没有被处理的错误(函数调用者如果不判断返回值的话)
       
    而异常是对于错误处理的面向对象的解决方案。它可以报告错误,但需要知道的是,并非由于错误而引发了异常,而仅仅是因为使用了raise。
    在Object Pascal中,抛出异常使用的是raise保留字。在任何时候(即使没有错误发生),raise都将会导致异常的发生。
   
    异常可以使得代码从异常发生处立刻返回,从而保护其下面的敏感代码不会得到执行。通过异常从函数返回和正常从函数返回(执行到函数末尾或执行了Exit)对于抛出异常的函数本身来说是没有什么区别的。区别在于调用者处,通过异常返回后,执行权会被调用者的try...except块所捕获(如果它们存在的话)。如果调用者处没有try...except块的话,将不会继续执行后续语句,而是返回更上层的调用者,直至找到能够处理该异常的try...except块。异常被处理后,将继续执行try...except块之后的语句,控制权就被留在了处理异常的这一层。当异常处理程序感觉对异常的处理还不够完整时,需要更上层调用者继续处理,可以重新抛出异常(使用简单的raise;即可)将控制权交给更上层调用者。
    如果根本就没有预设try...except块,则最终异常会被最外层的封装整个程序的VCL的try...except块所捕获。
    因此,不会有不被处理的异常,换句话说,也就是不会有不被处理的错误(虽然错误和异常并不能划等号)。这也是异常机制比使用返回错误代码方法的优越之处。另外,异常被抛出后,其控制流程的走向非常清晰明了,不会造成流程失去控制的情况。
   
    举个例子说明异常的工作机制,假设我们要打开某种特定格式的文件:
    先定义两个异常类(从Exception继承)
    EFileNotFound = class(Exception);
    EFileFormatErr = class(Exception);
   
    假设Form1上有一个按纽,按下按纽即打开文件:
    procedure TForm1.Button1Click(Sender: TObject);
    begin
        try
            ToOpenFile();
        except
            on EFileNotFound do
                ShowMessage(Sorry, I cant find the file);
            on EFileFormatErr do
                ShowMessage(Sorry, the file is not the one I want);
            on E:Exception do
                ShowMessage(E.Message);
        end;
    end;
   
    以及打开文件的功能函数:
    procedure ToOpenFile;
    var RetVal:Integer;
    begin
        //Some code to openfile

        RetVal := -1; //open failed

        if RetVal = 0 then //success
            Exit

        else if RetVal = -1 then
            Raise EFileNotFound.Create(File not found)

        else if RetVal = -2 then
            Raise EFileFormatErr.Create(File format error)

        else //other error
            Raise Exception.Create(Unknown error);
    end;
   
    程序中 TForm1.Button1Click 调用ToOpenFile,并预设了对ToOpenFile可能抛出的异常处理的try...except。当然,也可以对 TForm1.Button1Click 的异常处理代码进行简化:
    procedure TForm1.Button1Click(Sender: TObject);
    begin
        try
            ToOpenFile();
        except
            ShowMessage(Open file failed);
        end;
    end;
   
    使用异常解决了使用返回错误代码方法存在的问题,当然,使用异常也不是没有代价的。异常会增加程序的负担,因此滥用异常也是不可取的。写若干try...except和写数以千计的try...except之间是有很大区别的。用Chalie Calverts的话来说就是:“在似乎有用的时候,就应该使用try...except块。但是要试着让自己对这种技术的热情不要太过头”。
   
    另外,Object Pascal引入了独特的try...finally结构。前面我说过,通过异常从函数返回和正常从函数返回是没有什么区别的。因此,函数中的栈中的局部对象,会自动得到释放,而堆中的对象则不会。而然,Object Pascal的对象模型是基于引用的,其存在于堆中,而非栈中。因此,有时我们在通过异常从函数返回之前需要清理一些局域的对象资源。try...finally正是解决这个问题的。
   
    我改写了以上的 ToOpenFile 的代码,这次让ToOpenFile过程中使用了一些资源,并在异常发生后(或者不发生)从函数返回前都会释放这些资源:
    procedure ToOpenFile;
    var RetVal: Integer;
        Stream: TStream;
    begin
        //Some code to openfile
        Stream := TStream.Create;
        RetVal := -1; //open failed

        try
            if RetVal = 0 then //success
                Exit

            else if RetVal = -1 then
                Raise EFileNotFound.Create(File not found)

            else if RetVal = -2 then
                Raise EFileFormatErr.Create(File format error)

            else //other error
                Raise Exception.Create(Unknown error);
        finally
            Stream.Free;
        end;
    end;
   
    单步执行以上代码,可以看出,即使当RetVal的值为 0 时,执行Exit后,仍然会执行finally中的代码,然后再从函数返回。由此保证了局部资源的正确释放。
   
    try...except和try...finally的用途和使用场合是不同的,而很多初学者会将它们混淆。以下是笔者的一些个人认识:try...except一般用于调用者处捕获所调用的函数所抛出的异常并进行处理。而try...finally一般用于抛出异常的函数本身进行一些资源清理工作。
   
    面向对象编程提供了“异常”这种错误处理的方案。善而用之,会对我们的工作有好处,可以显著改善所编写代码的质量。
   
    Nicrosoft(nicrosoft@sunistudio.com)2001.7.25
    原文出处:东日文档(http://www.sunistudio.com/asp/sunidoc.asp


文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·在ASP.NET中使用Office Web Components (OWC)创建统计图-.NET教程,数据库应用
·windows系统下jsp+mysql+tomcat的配置-JSP教程,Application/Applet
·把aspx文件编译成DLL文件-.NET教程,Asp.Net开发
·Haneng.com的简单留言板制作源程序例子-ASP教程,ASP应用
·使用VB实现邮箱自动注册(一):表单自动提交-.NET教程,VB.Net语言
·VS.NET安装指南(To菜鸟)-.NET教程,Asp.Net开发
·web下水晶报表的使用!-.NET教程,Web Service开发
·C# 静态成员和方法的学习小结-.NET教程,数据库应用
·IIS的使用-ASP教程,ASP基础
·asp讲座之二:读取通过表单发送的数据
最新文章
·photoshop鼠绘实例:浪漫夏夜壁纸_photoshop教程
·买卖中小网站交易的一些细节问题_站长心得
·七招打造最安全的windows xp操作系统_windows xp
·做google adsense最佳和最重要的要诀_网赚技巧
·上下文关联广告清单(内文广告)推荐_网赚技巧
·广告联盟,痛定思痛_网赚技巧
·insenz首批广告费发放给站长_网赚技巧
·李彦宏:三分之一时间用在寻找人才_站长访谈
·中国汽车资源网杨锁民:网络寒冬时下海_站长访谈
·做it新闻资讯网站应先学新浪_站长心得
相关主题
西部数码虚拟主机

友情链接
CNNIC 西部数码
万网 自助建站
虚拟主机 asp空间
域名注册 域名
域名申请 主页空间
论坛空间 网站空间
国际域名 虚拟空间
空间租用 DDOS防火墙
成都主机托管 四川主机托管
主机租用 服务器租用
网站目录 自助建站
虚拟主机 网址大全
软件下载
自助链接
虚拟主机资讯 特价虚拟主机
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
发表评论 打印  刷新     关闭