程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#函數運行超時則終止執行(任意參數類型及參數個數通用版),

C#函數運行超時則終止執行(任意參數類型及參數個數通用版),

編輯:C#入門知識

C#函數運行超時則終止執行(任意參數類型及參數個數通用版),


    /// <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;
        }
    }

  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved