CER是.NET 2.0 CLR方面的重要改进,旨在帮助那些对稳定性高度苛刻的程序对付.NET Framework的不稳定因素。因为普通的程序很少会用到,所以一直没有对这个特性加以足够重视。现在碰巧在翻译书籍的过程中用到,就一起来学习一下。
首先,需要提到异步异常的问题。异步异常就是指OutOfMemoryException、StackOverflowException和ThreadAbortException等系统异常。说他们“异步”是因为他们可以在线程代码执行到任何地方的时候发生。一般的异常,比如FileNotFoundException是由代码自己产生的,因此可以用Try语句正常捕捉和处理。而异步异常则是CLR产生的。而且,这些异常都预示着非常严重的错误,代码自己通常都会手足无措。比方说内存耗尽了,代码自己即使Catch了也无济于事,都不知道刚刚哪一步出的问题,也不知道该怎么继续执行。ThreadAbortException通常是由Thread.Abort方法引发,如果要Abort的线程正在进行很关键的人物,比如修改一个全局对象的状态,那么发生ThreadAbortException可能会让整个程序的状态受损,进而产生错误的行为。因此,需要有种机制告诉CLR,我们要进行的事情很关键,不容打断,这就是CER——Constrained Execution Region。
声明CER很简单,先调用System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions()方法,再紧接一个Try...Catch...Finally块即可。注意,这个Try必须紧接着PrepareConstrainedRegions()方法,而且,只有Catch和Finally块的内容成为CER。如下所示

RuntimeHelpers.PrepareConstrainedRegions()
Try
Catch
    '注意,这里是CER
Finally
    '这里也是CER
End Try

一般情况下都用Finally块来做CER。CER与普通代码不同,在CER执行期间CLR不能发出异步异常。因此CLR就必须采取一些措施。首先CER会将ThreadAbortException推迟到CER结束之后才发生,这比较容易做到。第二,为了避免OutOfMemoryException,CLR会将CER中用到的所有方法(注意,这里是从代码静态观察,而不是实际调用的方法)以及这些方法所调用到的所有方法全都编译成本地代码,然后根据情况预测可能的内存不足并提前到CER之前引发。然而,这个方法并不能对付堆栈益处错误,所以这个方法会事先保留48K的栈空间以防万一。然而根据MSDN文档,StackOverflowException还是可能会发生的。
为了确保CER这种原理能够工作,首先CER之内不能在堆上进行任何分配操作,包括后台进行的分配操作。除了不能用New分配引用类型的对象之外,也不能进行装箱、线程同步锁操作或者访问多维数组。
刚才介绍到,CLR会事先编译CER中所有用到的方法以及它们各自调用的所有方法。那么聪明的人一定能看出一个问题,那就是通过委托和虚函数机制调用的方法无法事先准确判断,因而就无从准备。因此,RuntimeHelpers还提供了两个方法——PrepareMethod和PrepareDelegate。调用之前务必用这两个方法准备所有虚函数的实际版本和委托变量。使用CER是需要极其小心准备的,因此不是随随便便使用的特性。RuntimeHelpers还有许多其它方法对应各种有变数的情况。总之,CER的宗旨就是在执行之前将所有可以知道的情况尽数分析透彻以便提前判断CER中的操作到底有没有可能顺利完成。
下面用ThreadAbortException来做一个试验,因为这个异常是最容易引发的:

Imports System.Runtime.CompilerServices
Imports System.Threading

Module Module1Module Module1

    Dim globalArray() As Integer

    Sub Main()Sub Main()

        globalArray = New Integer(50000000) {}


        Dim t As New Thread(AddressOf Thread1)
        t.Start()
        t.Abort()
        t.Join()

        Console.WriteLine(AllEquals(globalArray, 100))
    End Sub

    Function AllEquals()Function AllEquals(Of T)(ByVal arr() As T, ByVal value As T) As Boolean
        For i As Integer = 0 To arr.Length - 1
            If Not arr(i).Equals(value) Then Return False
        Next
        Return True
    End Function

    Sub Thread1()Sub Thread1()
        RuntimeHelpers.PrepareConstrainedRegions()
        Try
        Finally

            For i As Integer = 0 To 50000000
                globalArray(i) = 100
            Next

        End Try
    End Sub

End Module

先把准备CER的代码注释掉,可以发现这个方法不是总能执行成功的,ThreadAbortException可能会将数组的操作打断,以至于留下不正常的状态。如果在你的计算机上该方法不会失败,可以尝试改变数组的大小。接下来应用CER,会发现出现异常时程序执行的速度剧烈下降,但是最终方法总能够成功地完成。这就是CER所带来的好处。

.NET 2.0 CER学习笔记相关推荐

  1. mysql查询数据为0的所有字段6_MySQL8.0 初级学习笔记(六)查询数据

    MySQL8.0 初级学习笔记(六)查询数据 MySQL8.0 初级学习笔记(六)查询数据 查询有多种方法:单表查询,使用集合函数查询,连接查询,子查询,合并查询结果,为表和字段取别名,使用正则表达式 ...

  2. 日语课程0基础学习笔记——第一课

    学习目标: 编程0基础学习笔记--前言 这是一个个人使用的日语学习记录博客!根据B站的up日语教程一直跟下来,从第一天开始记录.后续会把我学习的内容和知识点尽量多的记录在这个博客中,不仅是方便自己复习 ...

  3. away3d 4.0.9Gold 学习笔记 加载模型(6)

    学习笔记提供模型和贴图请勿用于商业用途. 1 package 2 { 3 import away3d.containers.ObjectContainer3D; 4 import away3d.con ...

  4. 0.数据结构学习笔记大纲

    推荐学习参考书籍: 实体课本:  1.严蔚敏.吴伟民编著的教材(都是伪算法) 实现代码:    高一凡 数据结构概述 定义:          我们如何把现实中大量而复杂的问题以特定的数据类型和特定的 ...

  5. 【学无止境】 基于ThinkPHP的OAuth2.0实现 ----OAuth2.0 个人学习笔记 Two

    ThinkPHP 结合 OAuth2.0 准备工作 第一我们得准备好OAuth2.0的源码包,下载地址点这里. 我们将下载好的源码包放在thinkphp的vendor文件夹下面.这里注意只要src文件 ...

  6. 【学无止境】基于ThinkPHP的OAuth2.0实现 ------ OAuth2.0个人学习笔记 One

    前言 最经要定义一些接口于是接触到了OAuth2.0这样的第三方接口机制,所以就简单的了解下,把学习感想发在这里以便以后参考回顾 了解 OAuth2.0 其实网上有一篇大神阮一峰写的博文已近写的很好了 ...

  7. hbase1.1.1 连接集群_HBase-1.0.1学习笔记(一)集群搭建

    鲁春利的工作笔记,好记性不如烂笔头 如下配置参照了http://hbase.apache.org/book.html,详见:hbase-1.0.1.1/docs/book.html 环境配置 1.安装 ...

  8. origin8.0 绘图学习笔记

    今天是第一次学习使用origin8.0来绘图和进行数据分析,现将学习过程中的点滴纪录在此,以便后续回顾学习. --------------------------------------------- ...

  9. TensorFlow2.0基础学习笔记

    创建张量 import tensorflow as tfprint("Tensorflow version:", tf.__version__) # 检查版本号 print(&qu ...

最新文章

  1. Oracle的ORA-02292报错:违反完整性约束,已找到子记录
  2. 全卷积神经网路【U-net项目实战】U-Net网络练习题: Kaggle - 2018 Data Science Bowl
  3. 爱情,这种高级玩意儿--一个码农的自白
  4. C#基础--类/接口/成员修饰符,多态、重载、重写,静态和非静态
  5. Quartus16.0如何使用TCL脚本
  6. java工程引入scala_引入ReactiveInflux:用于Scala和Java的无阻塞InfluxDB驱动程序,支持Apache Spark...
  7. python-环境篇-Anaconda的安装
  8. es6 for...of 循环
  9. f2fs系列之二: 重要的数据结构
  10. android动态添加控件在指定位置,Android 如何动态添加 View 并显示在指定位置。
  11. 测试线程池(Java)
  12. Ubuntu 16.04中的Dock的应用顺序调整
  13. 图文详解互联网根基之HTTP
  14. 神经网络加速器设计研究:寒武纪DianNao论文阅读
  15. Mac下一款好用的UML图绘制工具(StarUML)
  16. 花生壳内网穿透图文教程
  17. 2054339-01-2,N-Boc-N-bis(PEG2-acid)它可以在活化剂(如EDC或HATU)存在下与伯氨基反应
  18. laragon 更换php的版本
  19. java大学生网上请假系统ssm框架
  20. YOLOv7 训练前手动计算锚定框

热门文章

  1. 改变UITableView的headerView、footerView背景颜色
  2. ExtJs十三(ExtJs Mvc图片管理之三)
  3. android电话拨号器
  4. IDC对SIEM市场的估测
  5. ASP.net 2.0 Migrating系列 - Master Pages 感触
  6. python里unexpected eof while parsing_使用Python编程时的10个注意事项
  7. C语言——四字节对齐(4对齐后是4, 5对齐后是8)
  8. 犹豫了许久,还是写个年总结记录一下吧
  9. 读QT5.7源码(三)Q_OBJECT 和QMetaObject
  10. 系统安全攻防战:DLL注入技术详解