CLR内部异常(中)
不捕捉某一个异常
常常有这种情况,代码不需要捕捉异常,但需要执行一些清理或者修正操作。虽然不总是,支持物(holders)经常用在这种场景里。在支持物(holders)不适用的情况里,CLR提供了两个“finally”块的变种。
EX_TRY_FOR_FINALLY
当需要在代码退出时执行修正操作时,一个finally块就比较合适。在CLR里有一系列的宏来实现try/finally:
EX_TRY_FOR_FINALLY // code EX_FINALLY // exit and/or backout code EX_END_FINALLY
EX_HOOK
经常有这种情况,只在某种异常抛出的时候需要执行修正代码。对这些情况,EX_HOOK跟EX_FINALLY很类似,但是“勾子(hook)”子句只在有异常的时候执行。异常会自动在退出“勾子”子句之前再次抛出。
EX_TRY // code EX_HOOK // code to run when an exception escapes the “code” block. EX_END_HOOK
这个结构比简单的EX_CATCH配上EX_RETHROW块更好一些,因为其可以捕捉堆栈溢出异常(并向上展开堆栈),并再次抛出一个新的堆栈溢出异常。
抛出异常
在CLR里抛出异常其实就是下面的函数调用:
COMPlusThrow ( < args > )
有很多重载函数,但思路基本上就是向COMPlusThrow传入某个异常作为参数。异常类型由Rexcep.h中的一系列宏生成,如kAmbiguousMatchException, kApplicationException等类型。(重载函数)的其他参数指定资源和替代性文字。可以参考报告了类似异常的代码来选择异常类型。
以下是一些预定义的异常变种:
COMPlusThrowOOM();
最终调用ThrowOutOfMemory()函数,其抛出C++的OOM(内存不足)异常。它抛出一个预先创建的异常,因为不能在内存不足的情况下再找出内存创建这个异常!
当获取这个异常对应的托管异常时,CLR首先会尝试分配一个新托管对象[1],如果失败的话,那么就返回一个预先分配的,全局共享的内存不足异常对象。
[1] 毕竟,如果申请分配2G大小的数组失败,申请一个小对象还是可以试试的。
COMPlusThrowHR(HRESULT 问题HR);
如果你有IErrorInfo的话,有很多重载可用。还有一些惊人复杂的代码来指出一个HRESULT值对应哪种异常:
COMPlusThrowWin32(); / COMPlusThrowWin32(hr);
基本上是从Win32错误返回值抛出异常:HRESULT_FROM_WIN32(GetLastError())
COMPlusThrowSO();
抛出一个堆栈溢出(SO)异常。注意这个不是一个硬性的堆栈溢出,只是在可能导致硬性堆栈溢出的时候抛出的异常。
跟内存不足异常(OOM)类似,其抛出一个预先分配的C++堆栈溢出异常。跟OOM不同,当获取托管异常对象时,CLR总是返回预先分配的,全局共享的堆栈溢出异常对象。
COMPlusThrowArgumentNull()
抛出“参数不能为空”异常的辅助函数。
COMPlusThrowArgumentOutOfRange()
如名所示。
COMPlusThrowArgumentException()
另一个无效参数相关的异常。
COMPlusThrowInvalidCastException(thFrom, thTo)
传入强制转换的源类型和目的类型,这个函数可以返回一个相当不错的异常消息。
EX_THROW
这个是非常底层的抛出异常的函数,普通代码基本不用。很多COMPlusThrowXXX函数在内部使用EX_THROW,跟其它特定的ThrowXXX函数类似。最好少用EX_THROW,尽量使用封装好的函数以隐藏异常机制的细节。当然,如果没有合适的Throw函数可用,使用EX_THROW是可以接受的。
这个宏接受两个参数,要抛出的异常类型(C++ Exception类的某些子类),和用括号括起来的传递给该类型异常的构造函数的参数列表。
作者:懿民
链接:https://www.jianshu.com/p/a235f2ea6be1
来源:简书
原文地址:https://www.cnblogs.com/yilang/p/11833486.html
- SQL员工部门表综合查询60题
- 如何对Scala中集合(Collections)进行排序
- 小白教程——安装和使用PyCharm
- 如何在 Scala 中科学地操作 collection(一)集合类型与操作
- Redis 一二事(2) - 在spring中使用jedis 连接调试单机redis以及集群redis
- 用 Python 制作微信好友个性签名词云图
- 用 Python 查看微信好友位置信息
- 用 Python 分析微信好友性别比例
- FreeMarker静态模板结合spring展示
- 源码阅读之Vector
- 用 Python 实现聊天机器人
- 用 Python 实现雪花效果
- CentOS6.8_Spark单机部署
- 3.2 Spark调度机制
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Python logging模块异步线程写日志实现过程解析
- php-fpm重启导致的程序执行中断问题详解
- Python Socket TCP双端聊天功能实现过程详解
- django 将自带的数据库sqlite3改成mysql实例
- 利用python对mysql表做全局模糊搜索并分页实例
- PHP chop()函数讲解
- Linux下安装Memcached服务器和客户端与PHP使用示例
- PHP xpath()函数讲解
- CentOS7编译安装php7.1的教程详解
- PHP addcslashes()函数讲解
- 浅谈优化Django ORM中的性能问题
- PHP chr()函数讲解
- iOS音视频接入 - TRTC常见问题
- PHP常见的几种攻击方式实例小结
- PHP strripos函数用法总结