Structed Exception Handler 学习总结(四)

来源:互联网 发布:最火的网络歌曲 编辑:程序博客网 时间:2024/05/17 02:19

1.  try-finally 语句的基本形式

__try{    //guarded code}__finally{    //termination handler}

termination handler无论在guarded code以何种方式退出都会被调用。guarded code的退出方式有如下三种:

a. 正常退出该代码块

b. 在执行guarded code时发生异常

c. 在执行guarded code时遇到return语句或者goto语句(无条件跳转)

在这三种情况下termination handler都会被执行。其中第一种方式,常常用来对guarded code中申请的资源进行释放和清理,这也是try-finally语句最为常见的一种用法。

 

2.  多个finally块的执行流程

For example, suppose a series of function calls links function A to function D, as shown in the following figure. Each function has one termination handler. If an exception is raised in function D and handled in A, the termination handlers are called in this order as the system unwinds the stack: D, C, B.

Order of Termination-Handler Execution

实例代码如下:

void FA(){     __try     {         _tprintf_s(TEXT("FA: __try\n"));     }     __finally     {         _tprintf_s(TEXT("FA: __finally\n"));     }     _tprintf_s(TEXT("FA: FA\n"));}void FB(){     __try     {         FA();         _tprintf_s(TEXT("FB: __try\n"));     }     __finally     {         _tprintf_s(TEXT("FB: __finally\n"));     }     _tprintf_s(TEXT("FB: FB\n"));}void FC(){     __try     {         FB();         _tprintf_s(TEXT("FC: __try\n"));     }     __finally     {         _tprintf_s(TEXT("FC: __finally\n"));     }     _tprintf_s(TEXT("FC: FC\n"));}int _tmain(){     __try     {         FC();         _tprintf_s(TEXT("main: __try\n"));     }     __finally     {         _tprintf_s(TEXT("main: __finally\n"));     }        _tprintf_s(TEXT("main: main\n"));     return 0;}

 

其执行结果如下:

可见所以的finally块都被执行了。

 

3.  编写try-finally语句的最佳实践

在编写try-finally块时,要注意尽量不要使用return,continue, break,goto语句,因为SEH机制为了保证__finally块中语句被执行,会生成额外的代码来实现,这对程序的性能是有害的(当然,如果我们使用了这些语句,程序也是可以编译通过的,也没有错误),有可能大量使用栈,从而导致栈异常。

 

4.  try-finally语句的使用示例

//没有使用SEH的代码

在编写上述函数时未使用SEH机制(try-finally),其中为了完成对错误的处理,在该函数的实现中出现了大量的用于流程控制(函数返回)的return语句,同时还大量重复使用了CloseHandler和VirtualFree函数来对该函数申请的资源进行处理,这些错误检查代码使得整个函数难以阅读,进而造成该函数难以理解,修改和维护

 

//使用SEH来编写该函数

如上图所示,整个函数的资源清理全部放到__finally块中,使得整个函数的代码简洁,干净了许多,代码也更容易阅读和维护。

使用try-finally块的理由:

原创粉丝点击