正确使用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 ...
随机推荐
- python __name__ 变量的含义
python __name__ 变量的含义 if __name__ == '__main__': tf.app.run() 当python读入程序时,会初始化一些系统变量.如果当前程序是主程序,__n ...
- 全平台轻量级 Verilog 编译器 & 仿真环境
一直苦于 modelsim 没有Mac版本,且其体量过大,在学习verilog 时不方便使用. 终于找到一组轻量级且全平台 ( Linux+Windows+macOS ) 的编译仿真工具组. Icar ...
- java四则运算生成器
题目描述: 从<构建之法>第一章的 "程序" 例子出发,像阿超那样,花二十分钟写一个能自动生成小学四则运算题目的命令行 "软件",满足以下需求: 除 ...
- 201521123036 《Java程序设计》第8周学习总结
本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 1.2 选做:收集你认为有用的代码片段 HashMap自定义排序 List<Map.Entry<Stri ...
- 201521123065 《Java程序设计》第5周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 1.2 可选:使用常规方法总结其他上课内容. 1.ArrayList只能存放对象: 2.对象包装类之间使用equals进行比较 ...
- 201521145048《Java程序设计》第5周学习总结
1. 本章学习总结 2. 书面作业 Q1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误.并分析输出结果. 错误 ...
- 201521123035《Java程序设计》第二周学习总结
1.本周学习总结 这周学习了各种类与对象,还有基本类型的打包器,最主要的是字符串对象,老师还特地花了一节课时间讲解代码与习题. 2.书面作业 1.使用Eclipse关联jdk源代码,并查看String ...
- 201521123087 《Java程序设计》第11周学习总结
1. 本周学习总结 2. 书面作业 本次PTA作业题集多线程 互斥访问与同步访问完成题集4-4(互斥访问)与4-5(同步访问)1.1 除了使用synchronized修饰方法实现互斥同步访问,还有什么 ...
- **********MySql查询方法重要**********
分析问题要分步,查询每一步的结果,最后连起来 例如下面有四张表让你查询 查询选修“3-105”课程的成绩高于“109”号同学成绩的所有同学的记录. 第一部,找到课程编号为3-105的记录中学号为109 ...
- iOS启动图-从网络获取的gif图,在本地一直是没有动画,还模糊的
背景介绍:APP启动页,常有静态图加链接,gif加链接,短视频等几种形式.我们APP前期只有静态图这一种,功能已经实现.之后,有了添加gif的需求,按理说,只要添加一个类型判断,按照数据类型,通过不同 ...