在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
在日常的代码中,经常会遇到执行一段代码,无法控制执行的时间, 例如匹配一段非常复杂的正则,假设匹配时间超过30s可能即使匹配出来结果,我们也会放弃,因为他所消耗的资源太大了,因此就需要一个方法的超时处理功能 以下这个方法包含两个核心的方法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 }
这是我第一次在园子里发博客,希望园友们多多给意见或建议, |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论