不捕捉某一个异常

常常有这种情况,代码不需要捕捉异常,但需要执行一些清理或者修正操作。虽然不总是,支持物(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_TRY_FOR_FINALLY是基于SEH(Windows操作系统异常处理机制),而不是C++的异常处理机制。C++编译器不允许在一个函数里混合使用SEH和C++异常处理机制。有自动析构函数的局部变量要求C++异常处理机制以执行其析构函数。因此,使用了EX_TRY_FOR_FINALLY宏的函数不能同时使用EX_TRY,也不能有使用了自动析构函数的局部变量。

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
来源:简书

CLR内部异常(中)的更多相关文章

  1. CLR内部异常(上)

    当我们提到CLR里的“异常”,要注意一个很重要的区别.有通过如C#的try/catch/finally暴露给应用程序,并由运行时提供机制全权实现的托管异常.也有运行时自己使用的异常.大部分运行时开发人 ...

  2. CLR内部异常(下)

    直接使用SEH 有些情况里直接使用SEH会更合适一些.特别是,如果需要在第一次遍历(first pass - SEH异常处理流程里的第一遍处理)时需要执行某些操作时,也就是在堆栈向上展开之前,SEH是 ...

  3. 其他信息: 具有固定名称“Npgsql”的 ADO.NET 提供程序未在计算机或应用程序配置文件中注册或无法加载。有关详细信息,请参阅内部异常

    其他信息: 具有固定名称“Npgsql”的 ADO.NET 提供程序未在计算机或应用程序配置文件中注册或无法加载.有关详细信息,请参阅内部异常 解决方法 在 App.config 的 configur ...

  4. 【性能诊断】六、并发场景的性能分析(windbg案例,大量的内部异常造成CPU飙升)

    在做产品的某个核心模块的性能优化时,发现压到100并发时应用服务器的CPU就飙升至90%以上,50并发以后TPS就基本定格在一个数值上.使用性能监视器收集应用服务器的数据,发现每秒的.NET CLR ...

  5. Dynamics AX 2012 R2 AIF 内部异常

        今天,Reinhard发现某个入站端口,突然一直报错: The server was unable to process the request due to an internal erro ...

  6. ORACL内部异常:

    ORACL内部异常: ORA-00001: 违反唯一约束条件 (.) ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 ORA-00019: 超出最大会话许可数 OR ...

  7. [ArgumentException: 可能证书“CN=JRNet01-PC”没有能够进行密钥交换的私钥,或者进程可能没有访问私钥的权限。有关详细信息,请参见内部异常。]

    堆栈跟踪: [CryptographicException: 密钥集不存在. ] System.Security.Cryptography.Utils.CreateProvHandle(CspPara ...

  8. TP5使用API时不可预知的内部异常

    最常见的错误形式例如 controller不存在或者 action不存在之类的 我们第一时间想到的 就是 使用 try{}catch(){} 来捕获 例如: /** * show方法在common里定 ...

  9. TP5内部异常API数据输出的自定义方法编写

    需求:利用postman进行请求api接口过程中 关于一些数据输出异常的情况下 我们希望通过自己编写一些类和方法 实现便于后端人员进行根据提示进行调试处理! 以下测试的时候 请设置 app_debug ...

随机推荐

  1. Java常用函数式接口--Predicate接口使用案例

    Java常用函数式接口--Predicate接口使用案例 该方法可以使用and来优化: 调用:

  2. nacos初探--作为配置中心

    什么是nacos Nacos 支持基于 DNS 和基于 RPC 的服务发现(可以作为springcloud的注册中心).动态配置服务(可以做配置中心).动态 DNS 服务. 官方介绍是这样的: Nac ...

  3. oracle学习笔记(三)

    索引: drop table test1 purge; drop table test2 purge; drop table test3 purge; drop table t purge; crea ...

  4. IQueryable,IEnumerable,IList区别

    IQueryable和IEnumerable都是延时执行(Deferred Execution)的,而IList是即时执行(Eager Execution)IQueryable和IEnumerable ...

  5. C#泛型集合之——链表

    链表基础 1.概述:C#中泛型集合中的链表—LinkedList 是一个双向链表,其结点为LinkedListNode 结构 其中,结点结构包含:Next,Previous,Value三部分.且结点中 ...

  6. Tomcat6项目移到Tomcat7 提示 404 解决方案

    一个项目在Tomcat6可以运行和正常访问,但是一部署到Tomcat7就提示404错误.那么可以通过以下方法解决: 找到项目下面的   WEB-INF  文件夹   用记事本打开  WEB.XML 找 ...

  7. react-router4的使用备注

    1.安装 react-router是核心库,在项目中不需要安装,web开发只需安装react-router-dom.native开发安装react-router-native. 2.url参数携带与获 ...

  8. k8s维护常用命令

    k8s维护 1. 不可调度 kubectl cordon k8s-node-1 kubectl uncordon k8s-node-1 #取消 2.驱逐已经运行的业务容器 kubectl drain ...

  9. php exec执行视频图片转换

    首先安装ffmpeg <?php set_time_limit(0) ; $cmd = "ffmpeg -i 'input/3.mp4' -r 1 -q:v 2 -f image2 i ...

  10. 【RAC】 RAC For W2K8R2 安装--RDBMS软件的安装(五)

    [RAC] RAC For W2K8R2 安装--RDBMS软件的安装(五) 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也 ...