從一次淺嘗則止的代碼優化說起(一) 簡單的異常分離


 

厭倦了程序中無處不在的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