首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

《CLR via C#》笔记:第4部分 核心机制(1)

,不管是不是抛出了异常 } //如果try块没有抛出异常,或者某个catch 块捕捉到异常,但没有抛出或 //重新抛出异常,就执行下面的代码 } try:执行一般性的资源清理操作...有System.Exception类型的公共属性 throw抛出异常。一个异常抛出时,CLR在内部记录throw指令的位置(抛出位置)。一个catch 块捕捉到该异常时,CLR记录捕捉位置。...在 catch 块内访问被抛出的异常对象的StackTrace属性,负责实现该属性的代码会调用CLR内部的代码,后者创建一个字符串来指出从异常抛出位置到异常捕捉位置的所有方法。...如何在缓解对代码状态的破坏情况下,进行错误的捕捉:(P420 1) 1、执行catch或 finally块中的代码时,CLR不允许线程终止。所以,可以把一些状态更改操作放到finally块中进行。...(P427 3) 未处理的异常 异常抛出时,CLR在调用栈中向上查找与抛出的异常对象的类型匹配的catch 块。没有任何catch 块匹配抛出的异常类型,就发生一个未处理的异常。

77410

编写高质量代码改善C#程序的157个建议

前言     自从.NET出现后,关于CLR异常机制的讨论就几乎从未停止过。迄今为止,CLR异常机制让人关注最多的一点就是“效率”问题。...另外,“异常”其名称本身就说明了它的发生是一个小概率事件。所以,因异常带来的效率问题会倍限制在一个很小的范围内。实际上,try catch所带来的效率问题几乎忽略的。...另一种规避因为异常而影响效率的方法是:Tester-doer模式,下文将详细阐述。   本章将给出一些在C#中处理CLR异常方面的通用建议,一帮助大家构建和开发一个运行良好和可靠的应用系统。   ...这里需要稍加强调的是,在catch(CommunicationException)这个代码块中,代码所完成的功能是“通知发送”而不是“发送”本身,因为我们要确保在catch和finally中所执行的代码是可以倍执行的...在本例的catch代码块中,不要真得编写发送邮件的代码,因为发送邮件这个行为可能会产生更多的异常,而“通知发送”这个行为稳定性更高(即不“出错”)。

1.3K31
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    关于.NET异常处理的思考

    在异常的处理中,我们可以在一个线程捕获异常,在另一个线程中重新抛出异常。异常抛出时,CLR会在调用栈中向上查找与抛出的异常类型匹配的catch块。...如果没有任何catch块匹配抛出的异常类型,就发生一个未处理异常。CLR检测到进程中的任何线程有一个位处理异常,都会终止进程。      ...CLR自上而下搜素一个匹配的catch块,所以应该教具体的异常放在顶部。...一旦CLR找到一个具有匹配捕获类型的catch块,就会执行内层所有finally块中的代码,”内层finally“是指抛出异常的tey块开始,到匹配异常的catch块之间的所有finally块。        ...三.DotNET的Exception类分析:       CLR允许异常抛出任何类型的实例,这里我们介绍一个System.Exception类:       1.Message属性:指出抛出异常的原因

    92150

    Try 和异常

    零、try…catch…finally try try 语句是用来进行错误处理或者清理错误的代码块 catch catch 代码块可以直接访问 Exception 对象,这个对象中包含了相关的错误信息...当 try 中的代码发生错误时,如果存在catch代码块,那么它将会被将会被执行,如果只存在 finally 代码块的话,他将在 try 代码块执行完毕后执行,如果存在 catch 代码块和 finally...但是这里不会影响程序的运行,因为报错的代码位于 try 中,try 将这个错误捕获到后,转给了 catch ,catch 对这个错误进行了处理。...如果是的话,抛出的错误将会传递个能兼容这个异常的 catch 代码块中,当 catch 处理完毕后将执行 try…catch 后面的语句,如果存在 finally 代码块,那么将会先执行 finally...如果不是,CLR 会将这个错误向上抛出给 函数的调用者,并重复这个过程。

    80310

    .net 读书笔记

    对 32 位处理器来说,应用程序完成进程初始化后,CLR 将在进程的可用地址空间上分配一块保留的地址空间,它是进程(每个进程可使用 4GB)中可用地址空间上的一块内存区域,但并不对应于任何物理内存,这块地址空间即是托管堆...推荐选择 foreach 来处理可枚举集合的循环结构 12.以多线程处理应对系统设计。 13.尽可能少地抛出异常,禁止将异常处理放在循环内。....NET中的异常 而对异常的理解往往存在或多或少的误解: 例如:异常就是程序错误,以错误代码返回错误信息就足够了。在系统中异常越多越能保证容错性,尽可能多的使用try/catch块来处理程序执行。...catch子句包含了异常出现时的响应代码,其执行规则是:一个try子句可以关联零个或多个catch子句,CLR按照自上而下的顺序搜索catch块。...如果筛选器识别该异常,则会执行该catch子句内的响应代码;如果筛选器不接受该异常,则CLR将沿着调用堆栈向更高一层搜索,直到找到识别的筛选器为止,如果找不到则将导致一个未处理异常。

    65010

    ASP.NET Core应用程序池崩溃问题分析

    数据字段包含错误号" 说明应用程序池异常崩溃后重启了。...抓取dump分析 为了找到程序池崩溃的原因,抓取dump进行分析,如何抓取dump见文档,使用DebugDiag工具进行抓取,抓取后使用DebugDiag进行初步分析,如下图: 可以看出是线程池中的线程抛出了异常...反编译调试 由于dump的分析报告没有给出根本原因,也不熟悉如何深入分析dump,因此换个思路,通过测试找到了问题必现的某个请求操作后,尝试进行反编译调试,看能不能找到引发异常的根本原因。...然而进行了多次调试操作后,因为异常是在某个线程中触发的,并没有跟踪到异常产生的位置。 结合dump分析结果给出的信息,尝试在一些异步的操作位置打断点,也没有跟踪到导致程序池崩溃的异常。...跟踪这段代码,发现了一个空指针异常。 其实这个异常在反编译调试的时候就发现了,抛出后clr捕获了异常,请求继续往下走,请求走完后又在clr代码中抛出了异常,然后程序池挂掉。

    32810

    Java 进阶之异常处理

    在 Java 中,异常是一个对象,该对象包装了方法内发生的错误事件,并包含以下信息: 与异常有关的信息,如类型 发生异常时程序的状态 其它自定义消息(可选) 此外,异常对象也可以被抛出或捕获。...AssertionError:抛出该异常以表明断言失败。 LinkageError:链接错误的子类表示一个类对另一个类有一定的依赖性;然而,后一个类在前一个类编译后发生了不兼容的变化。...如果 catch 块捕获了该异常类或该异常的超类,则将执行该 catch 块中的语句。然后,在该catch 块之后执行 finally 块中的语句。...实际上 Java 编译后,会在代码后附加异常表的形式来实现 Java 的异常处理及 finally 机制(JDK 1.4.2 之前,Java 编译器是使用 jsr 和 ret 指令来实现 finally...的角度来分析一下 try-catch-finally 的底层原理。

    74150

    原 Introduction to the

    实际上,运行时的检查次数很少。它们包括下面这些指令: 1.将一个基类的指针强制转换为派生类型(反过来的转换可以放在静态分析里)。 2.数组越界检查(如同内存安全一样的道理)。...3.将指针数组里的元素替换成一个新(指针)值。这点是因为CLR数组的自由转换规则(在后文分析)。...如果两个变量指向相同的对象(指针指向相同的第内),改变其中一个变量就会印象另外一个变量。...###异常 另一个CLR支持的高级语法功能是异常,异常让开发者能在程序发生异常是抛出任意对象,当一个对象抛出是,运行时搜索调用栈,寻找一个方法能catch到这个异常,如果这个catch找到了,程序从这个位置继续执行...当一个错误被catch到,通常情况下不能确定继续执行是否会导致其他的错误(由第一个错误导致),这是未来CLR可能未添加的功能,然而, 即使在当前实施的情况下, 异常也是向前迈出的一大步 (我们需要更进一步

    80990

    【面试八股文】每日一题:谈谈你对异常的理解

    t=9.0 每日一题-Java核心-谈谈你对异常的理解【面试八股文】   异常是程序在运行过程中出现的错误或不正常的情况。当程序执行过程中遇到无法处理的错误或者不符合预期的情况,就会抛出异常。...非受检异常是指在程序运行过程中出现的异常,无法在编译时被检测到。这些异常通常是由程序逻辑错误导致的,如空指针引用、数组越界等。非受检异常可以通过捕获和处理来避免程序的崩溃。...捕获异常通过try-catch语句块来实现,可以在catch块中对异常进行处理,如输出错误信息、记录日志等。抛出异常通过throw语句将异常传递给上层调用者来处理。...  分析如下的代码程序,给出输出结果,并给出原因 public class Demo02 { public static void main(String[] args) {...:bobo   原因:通过指令分析我们可以发现在 return 代码执行的时候会将局部变量保存在 栈帧的顶部,然后在finally中修改的还是原来的栈帧位置的局部变量,最终返回的信息还是栈帧顶部的变量,

    19620

    try catch finally 实现机制

    try-catch-finally.png 使用 javac 指令将其编译为class 文件,并使用javap -c -v -s 查看结果。...编译后的字节码.png 在编译后字节码中,每个方法都附带一个异常表(Exception table),异常表里的每一行表示一个异常处理器,由 from 指针、to 指针、target 指针、所捕获的异常类型...这些指针的值是字节码索引,用于定位字节码 其含义是在[from, to)字节码范围内,抛出了异常类型为type的异常,就会跳转到target表示的字节码处。...当触发异常的字节码索引值在某个异常条目的[from, to)范围内,则会判断抛出的异常与该条目想捕获的异常是否匹配。...每个try block, catch block 后侧,return指令之前,都会拷贝finally block的代码块。

    2.5K51

    C# checked和unchecked详解

    ,并允许值回滚.应用程序将若无其事的运行.相反,Microsoft Visual Basic总将溢出视为错误,并会在检测到溢出时抛出一个错误....而CLR提供了一些特殊的IL指令,允许编译器选择它认为最正确的行为。CLR有一个add指令,将作用是将两个值加到一起,但不执行溢出检查。...CLR还有一个add.ovf的指令,作用是将两个值加到一起,但会在抛出异常时抛出一个System.OverflowException异常。...除了用于加法运算的这两个IL指令外,CLR还为减、乘和数据转换提供了类似的IL指令,分别是sub/sub.ovf,sub/sub.ovf和conv/conv.ovf。...;//在checked语句块内,可以直接使用+=操作符,编译器自动会把值转换为byte,前提200必须在byte范围内 Console.WriteLine(b); } 4、关于基元类型进行算术操作产生溢出的建议

    99280

    C++ 异常机制分析

    若匹配成功,则执行catch块内的异常处理语句,然后接着执行try...catch...块之后的代码。...如果在当前的try...catch...块内找不到匹配该异常对象的catch语句,则由更外层的try...catch...块来处理该异常;如果当前函数内所有的try...catch...块都不能匹配该异常...在函数中返回局部变量的引用或指针几乎肯定会造成错误,同样的道理,在throw语句中抛出局部变量的指针或引用也几乎是错误的行为。...在catch块中,如果在当前函数内无法解决异常,可以继续向外层抛出异常,让外层catch异常处理块接着处理。...catch的参数对象没有关系,若catch参数对象是引用类型,可能在catch语句内已经对异常对象进行了修改,那么重新抛出的是修改后的异常对象;若catch参数对象是非引用类型,则重新抛出的异常对象并没有受到修改

    1.8K61

    详解Java中的checked异常和unchecked异常

    Java中的异常(Exception)是什么? 异常就是在程序执行期间发生的打断指令正常执行流程的一个不期望出现的事件。 在Java中,所有的错误和异常都继承自Throwable类。...一个方法应该清晰的表明哪些异常场景它会处理,哪些它不会处理。这是在方法语法中使用throw子句来定义的。 为了处理异常,我们必须在try-catch代码块的catch块中捕获该异常。...为了使程序能够编译通过,你必须用try-catch代码块来处理这个异常情况。下面给出的代码就完全可以正常编译。...unchecked异常例子 看下面给出的代码,这段代码编译时没有错误。...checked异常理想上不应该用于程序异常,但绝对应该用于资源错误和这种情况下的流程控制。 仅仅抛出方法内怎么也处理不了的异常。

    4.1K32

    java学习之路:29.异常处理

    一.异常概述 学习Java时,常常会遇到编译程序后,提示出现异常,异常时一个在程序执行期间发生的事件,它中断了正在执行的程序的正常指令流。...另外两个方法如下: getMessage() : 输出错误性质 toString() : 给出异常的类型与性质。...3.如果在当前抛出异常的方法中处理异常,可以使用try-catch语句块捕捉并处理,否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。...} 使用throws关键字将异常抛给上一级后,如果不想处理该异常,可以继续向上抛出,但最终要有能够处理该异常的代码。...通过throw抛出异常后,如果想在上一级代码中来捕获并处理异常,则需要在抛出异常的方法中使用throws关键字在方法的声明中指名要抛出的异常,如果要捕捉throw抛出异常,则必须使用try-catch语句块

    49111

    C++异常

    try: try 块中的代码标识将被激活的特定异常,它后面通常跟着一个或多个 catch 块。   如果有一个块抛出一个异常,捕获异常的方法会使用 try 和 catch 关键字。...try 块中放置可能抛出异常的代码,try 块中的代码被称为保护代码。...抛出异常对象后,会生成一个异常对象的拷贝,因为抛出的异常对象可能是一个临时对象,所以会生成一个拷贝对象,这个拷贝的临时对象会在被catch以后销毁。...,导致资源没释放,所以我们可以选择二次抛出异常,在catch内先清理资源,再把异常抛出到下一级。...在二次抛出的try代码块里的函数可能会有多层,可能会是不同的异常,这样异常出来之后就不能匹配了,或者被main函数内的catch(…)捕获,又会导致没法delete,实属治标不治本,但是我们二次抛出异常可以使用

    10110

    代码洁癖系列(六):处理错误

    前面我们提到过,try-catch代码块会破坏代码的结构。但是,我们在处理错误时又不得不使用try-catch代码块,这样才能让我们的程序保持健壮。...异常抛出的层级 我们不希望程序中充满了try-catch代码块,这样会使程序的可读性变差。因此,我们要适当的使用throw语句,将异常抛出。交给上一层去处理。...这会使我们的工作量增加好几倍。所以,我们的异常最好在本层进行统一处理,或者在抛出后的上一层就进行处理。 说明发生异常的环境 在Java中,系统异常通常会给出调用栈,便于我们进行问题的定位和调试。...对于我们自己抛出的异常,也应该给出异常发生的环境,例如列出调用栈,给出请求参数等等。 远离null值 我们在读、写代码时,一定有被好多层的空指针判断折磨的经历。...一不小心漏掉一个判断,那么程序就会出现空指针异常,这个异常要么被上层的catch捕获,要么直接抛出。很明显,这两种结果都不是我们想要的。怎么远离空指针异常呢? 首先,代码的返回值不要返回null。

    40920

    Java的”异常“超详细讲解

    Java的”异常“超详细讲解 前言: ​ 我们在写代码的时候,经常会遇到错误,并且编译器会给出相关提示 如: 这里就会显示 ArrayIndexOutOfBoundsException *(数组越界)*...​ }] 解释: try { }: 内部放的是可能出现异常的代码块(也有可能没有异常) 如果出现异常,则异常后续的代码均不会被执行,直接跳转到对应异常类的的catch内容 catch( ){...} ()小括号内是异常类类名 + 实例化的对象名(这里通常习惯用e表示) { } 花括号内表示的对应的异常处理内容 可以存在多个catch 也可以一个catch内写多个异常类型,只需要一个实例化对象名...finally{ } finally{}内的代码块,无论异常发生与否,始终会被执行 通常被用于资源的关闭,对资源进行回收。...注意事项: try块内抛出异常位置之后的代码将不会被执行 如果抛出异常类型与catch时异常类型不匹配,即异常不会被成功捕获,也就不会被处理,继续往外抛,直到 JVM收到后中断程序----异常是按照类型来捕获的

    10210

    编程体系结构(02):Java异常体系

    如下:空指针NullPointerException;数组下标越界ArrayIndexoutofBoundsException等。...需要特别说明的一点,在Spring框架中,事务触发多数是以是否抛出异常为标识来处理的,如果方法在事务控制内,方法内异常捕获但是最终没有抛出,那该事务则无效。...catch代码块执行,finally代码会被执行,执行完finally代码块之后继续执行后续代码; Catch匹配可能出现的异常类型,并在其中做补偿处理,例如出现异常情况,需要更新一个异常状态等,如果没有...catch块,后必须跟finally块,处理资源释放; Finally无论是否捕获异常,finally代码会被执行,也是面试中常见的异常问题之一,例如在finally代码块return,或者修改返回值等...3、异常日志 复杂的业务系统必备功能,异常日志体系,用来分析运行问题,作为系统不断优化的核心依据,通常会记录如下几块: 异常类型:分析异常发生的关键原因; 异常信息:通常会简单记录e.getMsg输出的内容

    63110

    C++:15---异常机制

    程序的执行权将转移到与之匹配的catch语句块中 如果一条throw表达式解引用一个基类指针,而这个指针指向于派生类对象,则抛出的对象被切掉的一部分是基类部分中的。...相反,如果参数为引用类型,则在语句块内改变参数,也就是改变对象本身 如果catch的参数为基类类型,则我们可以使用派生类类型的异常对象对其进行初始化。...类似于取代了throw说明 七、一些重要的注意事项 1.栈展开过程中局部对象自动销毁 我们知道,语句块在结束之后,块内的局部对象会自动销毁 栈展开中也是如此,如果栈展开中退出了某个块,代表该块生命周期已经结束...原因:若析构函数中放置try语句块,其后面释放资源等操作可能就不会执行,后果很危险 3.不可抛出局部对象的指针 上面介绍过,退出了某个块,则同时释放该块中局部对象使用的内存。...如果抛出了一个局部对象的指针,则在执行相对应的catch语句块之前,该对象已经被销毁了。因此,抛出一个指向局部对象的指针是错误的。

    79720
    领券