Structed Exception Handler 学习总结(四)

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块的理由:

posted @ 2013-10-19 20:05  a ray of sunshine  阅读(199)  评论(0编辑  收藏  举报