在平常的代碼中,常常會遇到執行一段代碼,沒法控制執行的時間,spa
例如匹配一段很是複雜的正則,假設匹配時間超過30s可能即便匹配出來結果,咱們也會放棄,由於他所消耗的資源太大了,所以就須要一個方法的超時處理功能.net
如下這個方法包含兩個核心的方法OutTimeSomeParemReturn與Wait線程
下面我模擬一個執行過程,假設如今須要執行一個方法Method,方法執行的超時時間是OutTime,取消對象爲cancelEvent,下面我來解釋下這兩個方法
Wait是用來等待超時的方法
1 private static void Wait(Thread t, TimeSpan OutTime, WaitHandle are, WaitHandle cancelEvent) 2 { 3 WaitHandle[] ares; 4 if (cancelEvent == null) 5 ares = new WaitHandle[] { are }; 6 else 7 ares = new WaitHandle[] { are, cancelEvent }; 8 int index = WaitHandle.WaitAny(ares, OutTime); 9 if ((index != 0) && t.IsAlive)//若是不是執行完成的信號,而且,線程還在執行,那麼,結束這個線程 10 { 11 t.Abort(); 12 t = null; 13 } 14 }
參數t爲執行Method的線程,OutTime超時時間,are當Method方法執行完時的信號對象,cancelEvent當沒有完成Method並須要取消執行時的取消信號
使用的是WaitHandle對象所帶的WaitAny方法,
等待are與cancelEvent兩個對象的信號,當其中一個對象調用Set方法時說明方法執行完,或是取消了,
若是當執行時間超過OutTime值時,也會結束等待,此時是執行Method超時了,須要強行中止Method方法的執行,即調用執行Method方法的線程t的About方法,把線程中止
OutTimeSomeParemReturn是用來調用所須要設置超時的執行方法,與調用Wait方法等待超時
public static object OutTimeSomeParemReturn(SomeParamsReturnDelegate Method, TimeSpan OutTime, object Param, WaitHandle cancelEvent) { object obj = null; AutoResetEvent are = new AutoResetEvent(false); Thread t = new Thread(delegate() { obj = Method(Param); are.Set(); }); t.Start(); Wait(t, OutTime, are, cancelEvent); return obj; }
參數Method爲須要執行的方法,OutTime超時時間,Param爲Method方法執行所須要的參數,cancelEvent爲取消信號
我使用了一個匿名的方法來執行Method方法,並傳入參數Param,當執行結束後,調用are的Set方法,通知等待方法,而且把方法Method所反回的值賦給obj,
而後調用等待方法,阻塞,直到Method方法執行完,或是取消,或是超時三者其一時,反回obj對象
其餘幾個方法爲OutTimeSomeParemReturn方法的變形,或是重載,下面是所有代碼
1 using System; 2 using System.Threading; 3 4 namespace OutTimeManager 5 { 6 /// <summary> 7 /// 超時類,可設置執行方法超時時間 8 /// 目前沒有添加取消方法,若有須要,可添加取消功能 9 /// </summary> 10 public class OutTimeClass 11 { 12 #region delegate 13 /// <summary> 14 /// 無參數,無反回值方法 15 /// </summary> 16 public delegate void NotParamDelegate(); 17 /// <summary> 18 /// 有參數,無反回值方法 19 /// </summary> 20 /// <param name="Params"></param> 21 public delegate void SomeParamsDelegate(object Params); 22 /// <summary> 23 /// 無參數,帶返回值方法 24 /// </summary> 25 /// <returns></returns> 26 public delegate object NotParamReturnDelegate(); 27 /// <summary> 28 /// 有參數,有反回值方法 29 /// </summary> 30 /// <param name="Params"></param> 31 /// <returns></returns> 32 public delegate object SomeParamsReturnDelegate(object Params); 33 #endregion 34 35 #region 超時方法 36 /// <summary> 37 /// 無參數,無反回值超時方法 38 /// </summary> 39 /// <param name="Method">執行方法</param> 40 /// <param name="OutTimeMilliseconds">超時時間(毫秒)</param> 41 public static void OutTimeNotParam(NotParamDelegate Method, int OutTimeMilliseconds) 42 { 43 OutTimeNotParam(Method, TimeSpan.FromMilliseconds(OutTimeMilliseconds)); 44 } 45 46 /// <summary> 47 /// 無參數,無反回值超時方法 48 /// </summary> 49 /// <param name="Method">執行方法</param> 50 /// <param name="OutTime">超時時間</param> 51 public static void OutTimeNotParam(NotParamDelegate Method, TimeSpan OutTime) 52 { 53 OutTimeNotParam(Method, OutTime, null); 54 } 55 56 /// <summary> 57 /// 無參數,無反回值超時方法 58 /// </summary> 59 /// <param name="Method">執行方法</param> 60 /// <param name="OutTime">超時時間</param> 61 /// <param name="cancelEvent">取消信號</param> 62 public static void OutTimeNotParam(NotParamDelegate Method, TimeSpan OutTime, WaitHandle cancelEvent) 63 { 64 AutoResetEvent are = new AutoResetEvent(false); 65 Thread t = new Thread(delegate() { Method(); are.Set(); }); 66 t.Start(); 67 Wait(t, OutTime, are, cancelEvent); 68 } 69 70 /// <summary> 71 /// 有參數,無反回值超時方法 72 /// </summary> 73 /// <param name="Method">執行方法</param> 74 /// <param name="OutTimeMilliseconds">超時時間(毫秒)</param> 75 /// <param name="Param">參數</param> 76 public static void OutTimeSomeParem(SomeParamsDelegate Method, int OutTimeMilliseconds, object Param) 77 { 78 OutTimeSomeParem(Method, TimeSpan.FromMilliseconds(OutTimeMilliseconds), Param); 79 } 80 81 /// <summary> 82 /// 有參數,無反回值超時方法 83 /// </summary> 84 /// <param name="Method">執行方法</param> 85 /// <param name="OutTime">超時時間</param> 86 /// <param name="Param">參數</param> 87 public static void OutTimeSomeParem(SomeParamsDelegate Method, TimeSpan OutTime, object Param) 88 { 89 OutTimeSomeParem(Method, OutTime, Param, null); 90 } 91 92 /// <summary> 93 /// 有參數,無反回值超時方法 94 /// </summary> 95 /// <param name="Method">執行方法</param> 96 /// <param name="OutTime">超時時間</param> 97 /// <param name="cancelEvent">取消信號</param> 98 /// <param name="Params">參數</param> 99 public static void OutTimeSomeParem(SomeParamsDelegate Method, TimeSpan OutTime, object Param, WaitHandle cancelEvent) 100 { 101 AutoResetEvent are= new AutoResetEvent(false); 102 Thread t = new Thread(delegate() { Method(Param); are.Set(); }); 103 t.Start(); 104 Wait(t, OutTime, are, cancelEvent); 105 } 106 107 /// <summary> 108 /// 沒參數,有反回值超時方法 109 /// </summary> 110 /// <param name="Method">執行方法</param> 111 /// <param name="OutTimeMilliseconds">超時時間(毫秒)</param> 112 /// <returns>反回object類型對象</returns> 113 public static object OutTimeNotParamReturn(NotParamReturnDelegate Method, int OutTimeMilliseconds) 114 { 115 return OutTimeNotParamReturn(Method, TimeSpan.FromMilliseconds(OutTimeMilliseconds)); 116 } 117 118 /// <summary> 119 /// 沒參數,有反回值超時方法 120 /// </summary> 121 /// <param name="Method">執行方法</param> 122 /// <param name="OutTime">超時時間</param> 123 /// <returns>反回object類型對象</returns> 124 public static object OutTimeNotParamReturn(NotParamReturnDelegate Method, TimeSpan OutTime) 125 { 126 return OutTimeNotParamReturn(Method, OutTime, null); 127 } 128 129 /// <summary> 130 /// 沒參數,有反回值超時方法 131 /// </summary> 132 /// <param name="Method">執行方法</param> 133 /// <param name="OutTime">超時時間</param> 134 /// <param name="cancelEvent">取消信號</param> 135 /// <returns>反回object類型對象</returns> 136 public static object OutTimeNotParamReturn(NotParamReturnDelegate Method, TimeSpan OutTime, WaitHandle cancelEvent) 137 { 138 object obj = null; 139 AutoResetEvent are = new AutoResetEvent(false); 140 Thread t = new Thread(delegate() {obj= Method(); are.Set(); }); 141 t.Start(); 142 Wait(t, OutTime, are, cancelEvent); 143 return obj; 144 } 145 146 /// <summary> 147 /// 有參數,有反回值超時方法 148 /// </summary> 149 /// <param name="Method">執行方法</param> 150 /// <param name="OutTime">超時時間</param> 151 /// <param name="Params">執行參數</param> 152 /// <returns>反回一個object類型方法</returns> 153 public static object OutTimeSomeParemReturn(SomeParamsReturnDelegate Method, int OutTimeMilliseconds, object Param) 154 { 155 return OutTimeSomeParemReturn(Method, TimeSpan.FromMilliseconds(OutTimeMilliseconds), Param); 156 } 157 158 /// <summary> 159 /// 有參數,有反回值超時方法 160 /// </summary> 161 /// <param name="Method">執行方法</param> 162 /// <param name="OutTime">超時時間</param> 163 /// <param name="Params">執行參數</param> 164 /// <returns>反回一個object類型方法</returns> 165 public static object OutTimeSomeParemReturn(SomeParamsReturnDelegate Method, TimeSpan OutTime, object Param) 166 { 167 return OutTimeSomeParemReturn(Method, OutTime, Param, null); 168 } 169 170 /// <summary> 171 /// 有參數,有反回值超時方法 172 /// </summary> 173 /// <param name="Method">執行方法</param> 174 /// <param name="OutTime">超時時間</param> 175 /// <param name="Params">執行參數</param> 176 /// <param name="cancelEvent">取消信號</param> 177 /// <returns>反回一個object類型方法</returns> 178 public static object OutTimeSomeParemReturn(SomeParamsReturnDelegate Method, TimeSpan OutTime, object Param, WaitHandle cancelEvent) 179 { 180 object obj = null; 181 AutoResetEvent are = new AutoResetEvent(false); 182 Thread t = new Thread(delegate() { obj = Method(Param); are.Set(); }); 183 t.Start(); 184 Wait(t, OutTime, are, cancelEvent); 185 return obj; 186 } 187 188 /// <summary> 189 /// 等待方法執行完成,或超時 190 /// </summary> 191 /// <param name="t"></param> 192 /// <param name="OutTime"></param> 193 /// <param name="ares"></param> 194 private static void Wait(Thread t, TimeSpan OutTime, WaitHandle are, WaitHandle cancelEvent) 195 { 196 WaitHandle[] ares; 197 if (cancelEvent == null) 198 ares = new WaitHandle[] { are }; 199 else 200 ares = new WaitHandle[] { are, cancelEvent }; 201 int index = WaitHandle.WaitAny(ares, OutTime); 202 if ((index != 0) && t.IsAlive)//若是不是執行完成的信號,而且,線程還在執行,那麼,結束這個線程 203 { 204 t.Abort(); 205 t = null; 206 } 207 } 208 #endregion 209 } 210 }
另覆上一個正則的超時方法,思路與上述相同,只是我把正則匹配的功能加上了.
1 using System; 2 using System.Text.RegularExpressions; 3 using System.Threading; 4 5 namespace AD818_JM 6 { 7 public class OutTimeRegex 8 { 9 /// <summary> 10 /// 正則解析 11 /// </summary> 12 /// <param name="regex">正則對象</param> 13 /// <param name="input">須要解析的字符串</param> 14 /// <param name="OutTimeMilliseconds">超時時間</param> 15 /// <returns></returns> 16 public static MatchCollection Matchs(Regex regex, string input, int OutTimeMilliseconds) 17 { 18 MatchCollection mc = null; 19 AutoResetEvent are = new AutoResetEvent(false); 20 Thread t = new Thread(delegate() { 21 mc = regex.Matches(input); 22 //注意,在這裏必定要把全部的匹配項遍歷一次,否則的話當在此方法外遍歷的話.也可能會出現等待狀況 23 foreach (Match m in mc) { } 24 are.Set(); }); 25 t.Start(); 26 Wait(t, TimeSpan.FromMilliseconds(OutTimeMilliseconds), are, null); 27 return mc; 28 } 29 30 /// <summary> 31 /// 等待方法執行完成,或超時 32 /// </summary> 33 /// <param name="t"></param> 34 /// <param name="OutTime"></param> 35 /// <param name="ares"></param> 36 private static void Wait(Thread t, TimeSpan OutTime, WaitHandle are, WaitHandle cancelEvent) 37 { 38 WaitHandle[] ares; 39 if (cancelEvent == null) 40 ares = new WaitHandle[] { are }; 41 else 42 ares = new WaitHandle[] { are, cancelEvent }; 43 int index = WaitHandle.WaitAny(ares, OutTime); 44 if ((index != 0) && t.IsAlive)//若是不是執行完成的信號,而且,線程還在執行,那麼,結束這個線程 45 { 46 t.Abort(); 47 t = null; 48 } 49 } 50 51 /// <summary> 52 /// 正則解析 53 /// </summary> 54 /// <param name="regex">正則對象</param> 55 /// <param name="input">須要解析的字符串</param> 56 /// <param name="OutTimeMilliseconds">超時時間</param> 57 /// <returns></returns> 58 public static Match Match(Regex regex, string input, int OutTimeMilliseconds) 59 { 60 Match m = null; 61 AutoResetEvent are = new AutoResetEvent(false); 62 Thread t = new Thread(delegate() { m = regex.Match(input); are.Set(); }); 63 t.Start(); 64 Wait(t, TimeSpan.FromMilliseconds(OutTimeMilliseconds), are, null); 65 return m; 66 } 67 } 68 }
這是我第一次在園子裏發博客,但願園友們多多給意見或建議,