C#函数运行超时则终止执行(任意参数类型及参数个数通用版)

现在有更方便的实现方式:
static void Main(string[] args)
{

    string input = " ";

    Task.Factory.StartNew(() => { input = Console.ReadLine(); }).Wait(10 * 1000);

    Console.WriteLine(input);
}

  

以下是原来的实现方式:
/// <summary>
/// 控制函数执行时间,超时返回null不继续执行
/// 调用方法
/// FuncTimeout.EventNeedRun action = delegate(object[] param)
/// {
///     //调用自定义函数
///     return Test(param[0].ToString(), param[1].ToString(), (DateTime)param[2]);
/// };
/// FuncTimeout ft = new FuncTimeout(action, 2000);
/// var result = ft.doAction("1", "2", DateTime.Now);
/// </summary>
public class FuncTimeout
{
    /// <summary> 
    /// 信号量 
    /// </summary> 
    public ManualResetEvent manu = new ManualResetEvent(false);
    /// <summary> 
    /// 是否接受到信号 
    /// </summary> 
    public bool isGetSignal;
    /// <summary> 
    /// 设置超时时间 
    /// </summary> 
    public int timeout;
    /// <summary> 
    /// 定义一个委托 ,输入参数可选,输出object
    /// </summary> 
    public delegate object EventNeedRun(params object[] param);
    /// <summary>   
    /// 要调用的方法的一个委托   
    /// </summary>   
    private EventNeedRun FunctionNeedRun;

    /// <summary> 
    /// 构造函数,传入超时的时间以及运行的方法 
    /// </summary> 
    /// <param name="_action">运行的方法 </param> 
    /// <param name="_timeout">超时的时间</param> 
    public FuncTimeout(EventNeedRun _action, int _timeout)
    {
        FunctionNeedRun = _action;
        timeout = _timeout;
    }

    /// <summary> 
    /// 回调函数 
    /// </summary> 
    /// <param name="ar"></param> 
    public void MyAsyncCallback(IAsyncResult ar)
    {
        //isGetSignal为false,表示异步方法其实已经超出设置的时间,此时不再需要执行回调方法。 
        if (isGetSignal == false)
        {
            //放弃执行回调函数;
            Thread.CurrentThread.Abort();
        }
    }

    /// <summary>
    /// 调用函数 
    /// </summary>
    /// <param name="input">可选个数的输入参数</param>
    /// <returns></returns>
    public object doAction(params object[] input)
    {
        EventNeedRun WhatTodo = CombineActionAndManuset;
        //通过BeginInvoke方法,在线程池上异步的执行方法。 
        var r = WhatTodo.BeginInvoke(input, MyAsyncCallback, null);
        //设置阻塞,如果上述的BeginInvoke方法在timeout之前运行完毕,则manu会收到信号。此时isGetSignal为true。 
        //如果timeout时间内,还未收到信号,即异步方法还未运行完毕,则isGetSignal为false。 
        isGetSignal = manu.WaitOne(timeout);

        if (isGetSignal == true)
        {
            return WhatTodo.EndInvoke(r);
        }
        else
        {
            return null;
        }
    }

    /// <summary>
    /// 把要传进来的方法,和 manu.Set()的方法合并到一个方法体。 
    /// action方法运行完毕后,设置信号量,以取消阻塞。 
    /// </summary>
    /// <param name="input">输入参数</param>
    /// <returns></returns>
    public object CombineActionAndManuset(params object[] input)
    {
        var output = FunctionNeedRun(input);
        manu.Set();
        return output;
    }
}

  

 

  

转载于:https://www.cnblogs.com/jiaru/p/4466457.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值