91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#中,函數運行超時的功能的實現

發布時間:2020-06-15 11:45:26 來源:網絡 閱讀:5912 作者:cnn237111 欄目:編程語言

主要使用BeginInvoke方法和ManualResetEvent類來實現。

BeginInvoke使得函數在線程池上異步運行,運行完成后,調用回調函數。

ManualResetEvent用于同步阻塞。

設計思想如下:

當函數在線程池中的某一線程上異步的運行的時候,ManualResetEvent阻塞當前線程,等待若干時間。

在等候期間,如果異步函數運行完畢,會對ManualResetEvent設置一個信號,使得阻塞的線程得以繼續運行下去。

如果等候超時了,則阻塞的線程也會取消阻塞,繼續運行下去,但是不再理會回調的函數。(即使回調函數仍然被調用),事實上,BeginInvoke創建的線程都是后臺線程,這種線程一但所有的前臺線程都退出后(其中主線程就是一個前臺線程),不管后臺線程是否執行完畢,都會結束線程,并退出。因此如果阻塞的主線程完全運行完畢退出,那么異步運行的線程也會退出,無論是否運行完畢。

語句isGetSignal = manu.WaitOne(timeout);就是阻塞當前線程一段時間。

該語句阻塞期間,不會對isGetSignal賦值,直到阻塞取消后,才會返回一個值給isGetSignal。

當阻塞是因為收到信號而取消的,得到的值是true。

當阻塞是因為超時而取消的,得到的值是false。

整個流程如下:

C#中,函數運行超時的功能的實現

把這些代碼邏輯封裝成一個類。

這個類就接受一個委托和一個超時時間作為構造函數。

把這個委托和 ManualResetEvent .Set();語句寫在一個方法體內,CombineActionAndManuset,因此CombineActionAndManuset的調用就是實現了方法運行完畢后,設置取消阻塞信號。

封裝后的代碼:

  1. public class FuncTimeout  
  2.    {  
  3.        /// <summary>  
  4.        /// 信號量  
  5.        /// </summary>  
  6.        public ManualResetEvent manu = new ManualResetEvent(false);  
  7.        /// <summary>  
  8.        /// 是否接受到信號  
  9.        /// </summary>  
  10.  
  11.        public bool isGetSignal;  
  12.        /// <summary>  
  13.        /// 設置超時時間  
  14.        /// </summary>  
  15.        public int timeout;  
  16.        /// <summary>  
  17.        /// 要調用的方法的一個委托  
  18.        /// </summary>  
  19.        public Action<int> FunctionNeedRun;  
  20.  
  21.        /// <summary>  
  22.        /// 構造函數,傳入超時的時間以及運行的方法  
  23.        /// </summary>  
  24.        /// <param name="_action"></param>  
  25.        /// <param name="_timeout"></param>  
  26.        public FuncTimeout(Action<int> _action, int _timeout)  
  27.        {  
  28.            FunctionNeedRun = _action;  
  29.            timeout = _timeout;  
  30.        }  
  31.  
  32.        /// <summary>  
  33.        /// 回調函數  
  34.        /// </summary>  
  35.        /// <param name="ar"></param>  
  36.        public void MyAsyncCallback(IAsyncResult ar)  
  37.        {  
  38.            //isGetSignal為false,表示異步方法其實已經超出設置的時間,此時不再需要執行回調方法。  
  39.            if (isGetSignal == false)  
  40.            {  
  41.                Console.WriteLine("放棄執行回調函數");  
  42.                Thread.CurrentThread.Abort();  
  43.            }  
  44.            else 
  45.            {  
  46.                Console.WriteLine("調用回調函數");  
  47.            }  
  48.        }  
  49.  
  50.        /// <summary>  
  51.        /// 調用函數  
  52.        /// </summary>  
  53.        /// <param name="param1"></param>  
  54.        public void doAction(int param1)  
  55.        {  
  56.            Action<int> WhatTodo = CombineActionAndManuset;  
  57.            //通過BeginInvoke方法,在線程池上異步的執行方法。  
  58.            var r=WhatTodo.BeginInvoke(param1, MyAsyncCallback, null);  
  59.            //設置阻塞,如果上述的BeginInvoke方法在timeout之前運行完畢,則manu會收到信號。此時isGetSignal為true。  
  60.            //如果timeout時間內,還未收到信號,即異步方法還未運行完畢,則isGetSignal為false。  
  61.            isGetSignal = manu.WaitOne(timeout);  
  62.              
  63.            if (isGetSignal == true)  
  64.            {  
  65.                Console.WriteLine("函數運行完畢,收到設置信號,異步執行未超時");  
  66.            }  
  67.            else 
  68.            {  
  69.                Console.WriteLine("沒有收到設置信號,異步執行超時");  
  70.            }  
  71.        }  
  72.  
  73.        /// <summary>  
  74.        /// 把要傳進來的方法,和 manu.Set()的方法合并到一個方法體。  
  75.        /// action方法運行完畢后,設置信號量,以取消阻塞。  
  76.        /// </summary>  
  77.        /// <param name="num"></param>  
  78.        public void CombineActionAndManuset(int num)  
  79.        {  
  80.            FunctionNeedRun(num);  
  81.            manu.Set();  
  82.        }  
  83.    }  

測試代碼:

 

  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.             FuncTimeout ft = new FuncTimeout(dosth, 3000);  
  6.             ft.doAction(6);  
  7.         }  
  8.  
  9.        static void dosth(int num)  
  10.         {  
  11.             for (int i = 0; i < num; i++)  
  12.             {  
  13.                 Thread.Sleep(500);  
  14.                 Console.Write(i);  
  15.             }  
  16.         }  
  17.     } 

 

當超時時間設置為5s的時候,方法未超時

C#中,函數運行超時的功能的實現

當超時時間設置為1s的時候,方法超時

C#中,函數運行超時的功能的實現

附件:http://down.51cto.com/data/2361797
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

贵南县| 东阳市| 图们市| 朝阳区| 永吉县| 南投市| 什邡市| 江门市| 通州区| 乐昌市| 呼图壁县| 南川市| 抚松县| 云浮市| 额尔古纳市| 高要市| 正定县| 靖西县| 遵义市| 鹤庆县| 应用必备| 连江县| 安丘市| 砚山县| 同心县| 志丹县| 什邡市| 芦山县| 高密市| 齐河县| 栾城县| 健康| 华坪县| 汉川市| 元氏县| 巴南区| 稷山县| 丹寨县| 容城县| 林州市| 喀喇沁旗|