正确使用Exception异常对象
一、异常的构成
new Exception() 创建异常对象
throw 抛出异常对象(主要性能损耗位置)
try{}catch{} 捕捉异常对象
C#里面异常对象分为两个子类ApplicationException、SystemException,前者主要是提供给应用程序自定义的异常类,后者是提供给系统定义的异常类
二、如何使用异常
异常的正常逻辑是:由底层抛出,由高层处理
1、底层方法或者提供给其他人使用方法内的一些参数过滤或其它异常应该向上抛出
如(借鉴现成代码懒得写了):
public void InsertUser(User user)
{
if(user==null)
{
throw new ArgumentNullException("参数user为null");
}
//调用Orm
}
2、上层应该加上try{}catch{}来捕捉异常并处理
如:
try
{
bll.InsertUser(null);
}
catch (ArgumentNullException e)
{
LogHelper.Write(e.Message);
}
3、避免一些错误的异常处理方式
如(借鉴现成代码懒得写了):
/*
用异常验证用户输入
用户输入的合法性验证是属于业务逻辑的一部分,绝对不要用异常去处理,注意,是用户输入,所以这个经验仅限于表现层逻辑
*/
//典型错误1
try
{
int i=int.Parse(textBox1.Text);
}
catch(Exception ex)
{
alert(“不要输入非数字”);
}
//典型错误2
void ValidateInput(int i)
{
if(i<&&i>)
{
throw new Exception("输入数据范围错误");
}
}
/*
将异常交由给底层处理
这个错误在于完全不验证用户输入而直接把数据的验证抛向数据库,等待数据库报错来判断用户输入的正确性,这个是非常致命的错误,很多注入漏洞都是由此产生的
*/
//典型错误3
try
{
string name=Request.QueryString["xx"];
List<User> userls=User.QueryUserByName(name);
}
catch(SqlException ex)
{
}
/*
完全不用异常机制
产生这个错误肯定是一个非常脑残的决定造成的。不过很多时候某些不了解异常机制的人,由于对异常的性能开销的恐惧感,经常会做出这么脑残的决定
性能倒是高了,但是系统异常怎么办呢?一旦数据库出错就只等着系统崩溃了。某些有经验的说我会把下面的try{}catch{}起来,不过那不是脱了裤子放屁么,异常都抛出来了,开销已经产生了,结果换来的是牺牲了异常对象的丰富信息而换来了畸形的系统逻辑。性能也没得到提高
*/
//典型错误4
public bool InsertUser(User user,ref int errcode)
{
if(user==null)
{
errcode=;//参数为空错误的代码 return false;
}
//调用Orm
}
三、异常的性能测试
结论:
1、new Exception() 异常对象和创建普通对象的性能损耗没太大差别
2、throw 抛出异常时会造成系统性能损耗,主要在于“填充运行的堆栈信息”、“记录异常快照”等
3、try{}catch{}不会造成明显的系统开销,加不加性能区别不大
4、对外提供的方法尽可能抛出异常,避免程序崩溃,使用时请继承ApplicationException基类
5、业务逻辑上的数据尽量用if{}else{}过滤掉,不要靠throw new Exception()来处理
6、异常在程序中无法避免,合理使用避免程序崩溃才是唯一正确的道路
(以上结论仅代表个人观点)
public class TyhTest
{
private string msg;
public TyhTest(string msg)
{
this.msg = msg;
}
} public class TyhException : ApplicationException
{
//这种写法是继承基类构造方法
public TyhException(string msg): base(msg)
{ }
} class Program
{
static void Main(string[] args)
{
int max = ;
int j = ;
string str = "a";
//==========
Stopwatch time1 = new Stopwatch();
time1.Start();
for (int i = ; i < max; i++)
{
try
{
if (j > && !string.IsNullOrEmpty(str))
throw new Exception("Exception异常");
}
catch (Exception e)
{ }
}
time1.Stop();
Console.WriteLine("抛出Exception异常耗时:" + time1.ElapsedMilliseconds);
//==========
Stopwatch time2 = new Stopwatch();
time2.Start();
for (int i = ; i < max; i++)
{
try
{
if (j > && !string.IsNullOrEmpty(str))
throw new ApplicationException("Exception异常");
}
catch (ApplicationException e)
{ }
}
time2.Stop();
Console.WriteLine("抛出ApplicationException异常耗时:" + time2.ElapsedMilliseconds);
//==========
Stopwatch time3 = new Stopwatch();
time3.Start();
for (int i = ; i < max; i++)
{
try
{
if (j > && !string.IsNullOrEmpty(str))
throw new TyhException("Exception异常");
}
catch (Exception e)
{ }
}
time3.Stop();
Console.WriteLine("抛出自定义TyhException异常耗时:" + time3.ElapsedMilliseconds);
//==========
Stopwatch time4 = new Stopwatch();
time4.Start();
for (int i = ; i < max; i++)
{
try
{
if (j > && !string.IsNullOrEmpty(str))
{ }
else
{ }
}
catch (Exception e)
{ }
}
time4.Stop();
Console.WriteLine("不抛异常用IF判断耗时:" + time4.ElapsedMilliseconds);
//==========
Stopwatch time5 = new Stopwatch();
time5.Start();
for (int i = ; i < max; i++)
{
try
{
var test = new TyhTest("创建对象");
}
catch (Exception e)
{ }
}
time5.Stop();
Console.WriteLine("创建普通对象TyhTest耗时:" + time5.ElapsedMilliseconds);
//==========
Stopwatch time6 = new Stopwatch();
time6.Start();
for (int i = ; i < max; i++)
{
try
{
var test = new Exception("创建异常对象");
}
catch (Exception e)
{ }
}
time6.Stop();
Console.WriteLine("创建异常对象Exception耗时:" + time6.ElapsedMilliseconds); Console.ReadKey();
}
}
(Stopwatch 不需要 new 很多个,代码复制粘贴的,请忽略,忽略,哈哈~)
正确使用Exception异常对象的更多相关文章
- Interrupted Exception异常可能没你想的那么简单!
摘要: 当我们在调用Java对象的wait()方法或者线程的sleep()方法时,需要捕获并处理InterruptedException异常.如果我们对InterruptedException异常处理 ...
- Atitit 跨平台异常处理(2)--------异常转换 -----java c# js异常对象结构比较and转换
Atitit 跨平台异常处理(2)--------异常转换 -----java c# js异常对象结构比较and转换 { "@type":"java.lang.Runti ...
- terminate called without an active exception异常
在gcc4.4下,采用回调机制写了一个类似std::thread的线程类. 但是使用时却发生了核心已转移的错误. main函数调用的代码大致是 int main(int argc, char *arg ...
- C# 各类常见Exception 异常信息
一直对报错有些迷惑的地方,什么时候try,catch那些Exception更合适,报错信息更能快速定位问题所在... 转载链接← 正文 Exception: 所有异常对象的基类. SystemExce ...
- python第三十课--异常(异常对象传递过程)
演示异常对象传递的过程(往上“抛”),并将其解决 def func1(): print('func1...') print(10/0) def func2(): print('func2...') t ...
- mvc 使用预置队列类型存储异常对象
using PaiXie.Utils; using System; using System.Collections.Generic; using System.Linq; using System. ...
- python基础之内置异常对象
前言 什么叫异常?简单来说就是程序运行发生了预计结果之外的情况从而导致程序无法正常运行.而python解释器将一些常见的异常情况在它发生时打包成一个异常对象,我们可以通过捕捉这些异常对象从而进行处理, ...
- Java Exception异常介绍
一:介绍java异常 异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程.Java通 过API中Throwab ...
- throws/throw Exception 异常应用
throws通常用于方法的声明,当方法中发生异常的时候,却不想在方法中对异常进行处理的时候,就可以在声明方法时, 使用throws声明抛出的异常,然后再调用该方法的其他方法中对异常进行处理(如使用tr ...
随机推荐
- dispatch emit broadcast
1.broadcast 事件广播 遍历寻找所有子孙组件,假如子孙组件和componentName组件名称相同的话,则触发$emit的事件方法,数据为 params. 如果没有找到 则使用递归的方式 继 ...
- 第1阶段——uboot分析之仿照bootm制作hello命令(7)
仿照bootm命令生成来制作一个hello命令,功能:打印出hello,world!和参数值 1.点击New File ,创建cmd_hello.c将./common/cmd_bootm.c的头文件复 ...
- [自制操作系统] 图形界面&VBE工具&MMIO显存&图形库/字库
本文记录了在JOS(或在任意OS)上实现图形界面的方法与一些图形库的实现. 本文中支持的新特性: 支持基本图形显示 支持中英文显示(中英文点阵字库) 相关:VBE VESA MMIO 点阵字库 Git ...
- 201521123086《java程序设计》第7周
本章学习总结 书面作业 1.ArrayList代码分析 1.1 解释ArrayList的contains源代码 以下是ArrayList的contains源代码: public boolean con ...
- 201521123054《Java程序设计》第4周总结
1. 本周学习总结 2. 书面作业 注释的应用 使用类的注释与方法的注释为前面编写的类与方法进行注释,并在Eclipse中查看.(截图) 面向对象设计(大作业1,非常重要) **2.1 将在网上商城购 ...
- JAVA课程设计——“小羊吃蓝莓”小游戏
JAVA课程设计--"小羊吃蓝莓"小游戏 1. 团队课程设计博客链接 http://www.cnblogs.com/HXY071/p/7061216.html 2. 个人负责模块或 ...
- 201521123052 《Java程序设计》 第12周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...
- PHP面向对象三大特性之一:封装
面向对象的三大特性:封装.继承.多态 1.封装 封装的目的:让类更加安全,做法是不让外界直接访问类的成员 具体做法:1.成员变为私有:访问修饰符(public.private.protected) ...
- Easyui DataGrid DateRange Filter 漂亮实用的日期区间段筛选功能
自定义扩展Jquery easyui datagrid filter组件实现对日期类型区间段的筛选功能.显示效果如一下 是不是非常实用 引用的jquery 组件是 Date Range Picker ...
- Oracle SQL*Plus 数据备份为 sql 文件
在某些比较严格的环境中,不提供像PL/SQL Developer 这样的工具供我们备份表数据时,使用SQL*Plus运行如下脚本内容导出数据. 1, 执行时登录SQL*Plus, 命令 @D: ...