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 }

 

这是我第一次在园子里发博客,希望园友们多多给意见或建议,

posted @ 2012-09-02 22:22  只会造轮子  阅读(3090)  评论(2编辑  收藏  举报