C#实现函数的超时退出功能
主要是用到了System.Threading.Tasks.TaskFactory的StartNew()函数
private static void Main(string[] args) { Console.WriteLine("Begin:" + DateTime.Now); bool ret = Process(string.Empty, 10000); Console.WriteLine("Result={0}", ret); Console.WriteLine("End:" + DateTime.Now); Console.WriteLine("Press any key to exit..."); Console.ReadKey(true); } private static bool Process(string param, int timeout) { bool ret = false; new System.Threading.Tasks.TaskFactory().StartNew(() => { ret = LongTimeFunc(); }).Wait(timeout); return ret; } private static bool LongTimeFunc() { System.Threading.Thread.Sleep(5000); return true; }
出处:https://blog.csdn.net/tongxin1004/article/details/81941342
=========================================================================================
C#: 一个方法执行超时 timeout 检查的实现
我们经常有这样的需求:如果一个方法的执行,超过了一个设定时间(timeout)就需要立即返回不再继续,这里我利用 C# 异步委托的 AsyncWaitHandle 来尽量简便的实现这一需求。
具体实现如下。注意,这里需要被调用的方法遵守 delegate TR TimeOutDelegate(T param); 形式的方法签名,如有其他需要,可以自行定制也很方便。
namespace TimeOutHelper { #region using directives using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; #endregion using directives internal class Program { public delegate TR TimeOutDelegate<in T, out TR>(T param); private static void Main() { Dictionary<Guid, string> result; Console.WriteLine(TimeoutFunction.Execute(Test, "Hello, World!", out result, TimeSpan.FromSeconds(3))); Console.WriteLine("Hello, World!"); Console.ReadKey(); } public static Dictionary<Guid, string> Test(string sourceString) { var result = sourceString.ToDictionary( character => Guid.NewGuid(), character => character.ToString(CultureInfo.InvariantCulture)); Thread.Sleep(4000); return result; } public static class TimeoutFunction { /// <summary> /// Execute a method with timeout check /// </summary> /// <typeparam name="T">Target method parameter type</typeparam> /// <typeparam name="TR">The result type of execution</typeparam> /// <param name="timeoutMethod">Target method</param> /// <param name="param">Target method parameter</param> /// <param name="result">The result of execution</param> /// <param name="timeout">Set timeout length</param> /// <returns>Is timeout</returns> public static Boolean Execute<T, TR>( TimeOutDelegate<T, TR> timeoutMethod, T param, out TR result, TimeSpan timeout) { var asyncResult = timeoutMethod.BeginInvoke(param, null, null); if (!asyncResult.AsyncWaitHandle.WaitOne(timeout, false)) { result = default(TR); return true; } result = timeoutMethod.EndInvoke(asyncResult); return false; } } } }
出处:https://blog.csdn.net/nista/article/details/49125701
=========================================================================================
主要是用到了System.Threading.Tasks.TaskFactory的StartNew()函数
private static void Main(string[] args) { Console.WriteLine("Begin:" + DateTime.Now); bool ret = Process(string.Empty, 10000); Console.WriteLine("Result={0}", ret); Console.WriteLine("End:" + DateTime.Now); Console.WriteLine("Press any key to exit..."); Console.ReadKey(true); } private static bool Process(string param, int timeout) { bool ret = false; new System.Threading.Tasks.TaskFactory().StartNew(() => { ret = LongTimeFunc(); }).Wait(timeout); return ret; } private static bool LongTimeFunc() { System.Threading.Thread.Sleep(5000); return true; }
出处:https://blog.csdn.net/tongxin1004/article/details/81941342
=========================================================================================
C#: 一个方法执行超时 timeout 检查的实现
我们经常有这样的需求:如果一个方法的执行,超过了一个设定时间(timeout)就需要立即返回不再继续,这里我利用 C# 异步委托的 AsyncWaitHandle 来尽量简便的实现这一需求。
具体实现如下。注意,这里需要被调用的方法遵守 delegate TR TimeOutDelegate(T param); 形式的方法签名,如有其他需要,可以自行定制也很方便。
namespace TimeOutHelper { #region using directives using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; #endregion using directives internal class Program { public delegate TR TimeOutDelegate<in T, out TR>(T param); private static void Main() { Dictionary<Guid, string> result; Console.WriteLine(TimeoutFunction.Execute(Test, "Hello, World!", out result, TimeSpan.FromSeconds(3))); Console.WriteLine("Hello, World!"); Console.ReadKey(); } public static Dictionary<Guid, string> Test(string sourceString) { var result = sourceString.ToDictionary( character => Guid.NewGuid(), character => character.ToString(CultureInfo.InvariantCulture)); Thread.Sleep(4000); return result; } public static class TimeoutFunction { /// <summary> /// Execute a method with timeout check /// </summary> /// <typeparam name="T">Target method parameter type</typeparam> /// <typeparam name="TR">The result type of execution</typeparam> /// <param name="timeoutMethod">Target method</param> /// <param name="param">Target method parameter</param> /// <param name="result">The result of execution</param> /// <param name="timeout">Set timeout length</param> /// <returns>Is timeout</returns> public static Boolean Execute<T, TR>( TimeOutDelegate<T, TR> timeoutMethod, T param, out TR result, TimeSpan timeout) { var asyncResult = timeoutMethod.BeginInvoke(param, null, null); if (!asyncResult.AsyncWaitHandle.WaitOne(timeout, false)) { result = default(TR); return true; } result = timeoutMethod.EndInvoke(asyncResult); return false; } } } }
出处:https://blog.csdn.net/nista/article/details/49125701
=========================================================================================
C#执行带超时功能的方法
在日常的代码中,经常会遇到执行一段代码,无法控制执行的时间,
例如匹配一段非常复杂的正则,假设匹配时间超过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 }
这是我第一次在园子里发博客,希望园友们多多给意见或建议,
出处:https://www.cnblogs.com/jiangming/archive/2012/09/02/TimeOutManager.html
=========================================================================================