zoukankan      html  css  js  c++  java
  • c# 调用方法超时直接返回的功能

    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

    =========================================================================================

  • 相关阅读:
    Java/android下哈希sha1和MD5的实现
    ANDROID SOCKET 开发
    UML补充
    TCP协议中的三次握手和四次挥手(转)
    uva 658 最短路
    uva 11280 最短路
    uva 10246 最短路
    uva 11747,kruskal 并查集
    uva 544 dijkstra
    uva 1395 瓶颈树
  • 原文地址:https://www.cnblogs.com/mq0036/p/12524138.html
Copyright © 2011-2022 走看看