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
=========================================================================================
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
=========================================================================================