从一次浅尝则止的代码优化说起(一) 简单的异常分离


 

厌倦了程序中无处不在的try...catch...finally,在年前出差回公司后快放假那段有点疼的日子里按照《代码整洁之道》中剥离异常捕获的思想写了段代码。
原理:
根据C#中的委托,将要执行的函数放入封装了try...catch...finally的函数库中,这边就叫  异常剥离函数。
一、参数众多的异常剥离

 1 /// <summary>
2 ///整洁函数
3 ///用来对委托进行try{}catch{} finally{}的封装
4 /// </summary>
5 public class CleanCodeInvoker
6 {
7 #region Func<out>
8 public static T InvokeDelegate<T> (Func<T,object[]>RunFunc,object[] agrs,Action FinalizeAction=null,Action<Exception> ExceptionAction=null)
9 {
10 try
11 {
12 RunFunc(args);
13 }
14 catch(Exception ex)
15 {
16 if(ExceptionAction!=null)
17 {
18 ExceptionAction(ex);
19 }
20 }
21 finally
22 {
23 if(FinalizeAction!=null)
24 {
25 FinalizeAction();
26 }
27 }
28 }
29 #endregion
30
31 }

此时,测试代码如下:

View Code
 1 public void Test()
2 {
3 Func<string,object[]> TestFunc=m=>Print(m[0].ToString(),m[1].ToString());
4 string msg="it is a test";
5 string symbol="!";
6 string returnValue=CleanCodeInvoker.InvokeDelegate<string>(TestFunc,new object[]{msg,symbol});
7 Console.WriteLine(returnValue);
8 Console.Read();
9
10 }
11
12 public string Print(string msg,string symbol)
13 {
14 string returnValue=string.Format("{0}{1}",msg,symbol);
15 Console.WriteLine(returnValue);
16 return returnValue;
17 }

写完测试代码后发现,这个函数的调用实在是麻烦,需要不停的进行参数类型的转换。于是脑门一拍,把调用时的object[]换成dynamic[]。咋一看代码,省了一堆的转换过程。但是,路过的公司前辈一句话又把我一棒子打回了原型:这样子做对性能的影响是致命的!

性能!!!!!!!!!!

测试后发现,dynamic的速率比装箱慢2.5倍左右!!!!!

好吧我不用dynamic了。

好吧,我不传参数了行不行!!! 

行!!!

测试代码如下:

 无参数的测试代码
 1 public void Test()
2 {
 3 string msg="it is a test";
4 string symbol="!";

5 Func<string> TestFunc=()=>Print(msg,symbol);
6 string returnValue=CleanCodeInvoker.InvokeDelegate<string>(TestFunc);
7 Console.WriteLine(returnValue);
8 Console.Read();
9
10 }
11
12 public string Print(string msg,string symbol)
13 {
14 string returnValue=string.Format("{0}{1}",msg,symbol);
15 Console.WriteLine(returnValue);
16 return returnValue;
17 }

此时,异常剥离函数修改如下:

 

 1 /// <summary>
2 ///整洁函数
3 ///用来对委托进行try{}catch{} finally{}的封装
4 /// </summary>
5 public class CleanCodeInvoker
6 {
7 #region Func<out>
8 public static T InvokeDelegate<T> (Func<T>RunFuncAction FinalizeAction=null,Action<Exception> ExceptionAction=null)
9 {
10 try
11 {
12 return RunFunc();
13 }
14 catch(Exception ex)
15 {
16 if(ExceptionAction!=null)
17 {
18 ExceptionAction(ex);
19 }
20 }
21 finally
22 {
23 if(FinalizeAction!=null)
24 {
25 FinalizeAction();
26 }
27 }
28 }
29 #endregion
30
31 }

这里必须注意下,当进行多线程调用时,传入的参数进行值拷贝以防止程序运行时读取脏数据。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM