<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        在.NET Core中使用異步編程的方法步驟

        來源:懂視網 責編:小采 時間:2020-11-27 22:34:38
        文檔

        在.NET Core中使用異步編程的方法步驟

        在.NET Core中使用異步編程的方法步驟:近期對于異步和多線程編程有些啟發,所以我決定把自己的理解寫下來。 思考:為什么要使用異步編程? 我們先看看同步方法和異步方法之前在程序中執行的邏輯: 1. 同步方法 static void Main(string[] args) { Console.WriteLine(${Dat
        推薦度:
        導讀在.NET Core中使用異步編程的方法步驟:近期對于異步和多線程編程有些啟發,所以我決定把自己的理解寫下來。 思考:為什么要使用異步編程? 我們先看看同步方法和異步方法之前在程序中執行的邏輯: 1. 同步方法 static void Main(string[] args) { Console.WriteLine(${Dat

        主線程在調用同步方法時,會直接在主線程中執行同步方法,這個時候若SyncTestMethod方法后面還有其它方法,都需要等待SyncTestMethod執行完成。

         

        2. 異步方法

        static void Main(string[] args)
        {
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:開始");
         // 調用異步步方法
         AsyncTestMethod();
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:結束");
         Console.ReadKey();
        }
        
        
        /// <summary>
        /// 異步方法
        /// </summary>
        /// <returns></returns>
        static async Task AsyncTestMethod() {
         await Task.Run(() => {
         for (int i = 0; i < 10; i++)
         {
         Console.WriteLine($"AsyncTestMethod");
         Thread.Sleep(10);
         }
         });
        }

        控制臺打印:

        2019-03-26 14:52:37 5237:開始
        2019-03-26 14:52:37 5237:結束
        2019-03-26 14:52:37 5237:AsyncTestMethod
        2019-03-26 14:52:37 5237:AsyncTestMethod
        2019-03-26 14:52:37 5237:AsyncTestMethod
        2019-03-26 14:52:37 5237:AsyncTestMethod
        2019-03-26 14:52:37 5237:AsyncTestMethod
        2019-03-26 14:52:37 5237:AsyncTestMethod
        2019-03-26 14:52:37 5237:AsyncTestMethod
        2019-03-26 14:52:37 5237:AsyncTestMethod
        2019-03-26 14:52:37 5237:AsyncTestMethod
        2019-03-26 14:52:37 5237:AsyncTestMethod

        主線程在調用異步方法時,將會新建一個子線程去執行異步方法,調用過AsyncTestMethod方法之后,將會直接執行AsyncTestMethod后面的方法,這個時候主線程不會等待異步方法執行完成;因為這個時候主線程無法知曉異步方法會在什么時候執行完成,所以此時也無法在主線程中直接獲取異步方法的返回,如果需要在異步方法執行完成之后再在主線程中執行其它方法,則需要使用Wait()來等待異步子線程執行完成。

        3. 等待(awiat)異步方法

        static void Main(string[] args)
        {
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:開始");
         // 調用異步步方法
         AsyncTestMethod();
         // 等待異步方法執行完成
         m1.Wait();
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:結束");
         Console.ReadKey();
        }
        
        
        /// <summary>
        /// 異步方法
        /// </summary>
        /// <returns></returns>
        static async Task AsyncTestMethod() {
         await Task.Run(() => {
         for (int i = 0; i < 10; i++)
         {
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:AsyncTestMethod");
         Thread.Sleep(10);
         }
         });
        }

        控制臺打印:

        2019-03-26 14:55:51 5551:開始
        2019-03-26 14:55:51 5551:AsyncTestMethod
        2019-03-26 14:55:51 5551:AsyncTestMethod
        2019-03-26 14:55:51 5551:AsyncTestMethod
        2019-03-26 14:55:51 5551:AsyncTestMethod
        2019-03-26 14:55:51 5551:AsyncTestMethod
        2019-03-26 14:55:51 5551:AsyncTestMethod
        2019-03-26 14:55:51 5551:AsyncTestMethod
        2019-03-26 14:55:51 5551:AsyncTestMethod
        2019-03-26 14:55:51 5551:AsyncTestMethod
        2019-03-26 14:55:51 5551:AsyncTestMethod
        2019-03-26 14:55:51 5551:結束

        主線程在調用異步方法時,將會新建一個子線程去執行異步方法,并且在調用AsyncTestMethod方法之后執行了對AsyncTestMethod方法的等待Wait(),這個時候主線程會等待異步方法執行完成,不會執行后續的方法,在AsyncTestMethod執行完成之后,等待結束,此時可以拿到異步方法AsyncTestMethod的返回值,然后再繼續執行主線程中的方法。

        4. 同步線程和異步線程關聯執行

        如有以下方法:

        static int Method1()
        {
         Thread.Sleep(200);
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:我計算了一個值耗費200ms");
         return 1;
        }
        static int Method200ms()
        {
         Thread.Sleep(200);
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:我做了一件耗費200ms的事情");
         return 200;
        }
        static int Method500ms(int index)
        {
         Thread.Sleep(500);
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:我做了一件耗費500ms的事情");
         return ++index;
        }
        static int Method1000ms()
        {
         Thread.Sleep(1000);
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:我做了一件耗費1000ms的事情");
         return 1000;
        }

        Method500ms()需要Method1()的返回值作為參數,如果所有的方法同步執行在最后計算a、b、c、d的和:

        static void Main(string[] args)
        {
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:開始");
         var a = Method1();
         var b = Method200ms();
         var c = Method500ms(a);
         var d = Method1000ms();
         var result = a+b+c+d;
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:最后得到的結果{result}");
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:結束");
         Console.ReadKey();
        }

        控制臺打印:

        2019-03-26 15:10:06 106:開始
        2019-03-26 15:10:06 106:我計算了一個值耗費200ms
        2019-03-26 15:10:06 106:我做了一件耗費200ms的事情
        2019-03-26 15:10:07 107:我做了一件耗費500ms的事情
        2019-03-26 15:10:08 108:我做了一件耗費1000ms的事情
        2019-03-26 15:10:08 108:最后得到的結果1203
        2019-03-26 15:10:08 108:結束

        同步執行的時候,需要逐一等待所有的方法執行完成,花費的時間顯然是所有的方法耗費的時間之和。

        對于以上四個方法,如果使用異步的方式來執行,將會很大程度的節省程序的運行時間,修改方法如下:

        static async Task<int> AsyncMethod1()
        {
         await Task.Run(()=> {
         Thread.Sleep(200);
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:我計算了一個值耗費200ms");
         });
         return 1;
        }
        static async Task<int> AsyncMethod200ms()
        {
         await Task.Run(() => {
         Thread.Sleep(200);
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:我做了一件耗費200ms的事情");
         });
         return 200;
        }
        static async Task<int> AsyncMethod500ms(int index)
        {
         await Task.Run(() => {
         Thread.Sleep(500);
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:我做了一件耗費500ms的事情");
         });
         return ++index;
        }
        static async Task<int> AsyncMethod1000ms()
        {
         await Task.Run(() => {
         Thread.Sleep(1000);
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:我做了一件耗費1000ms的事情");
         });
         return 1000;
        }

        使用異步的方式來調用方法:

        static void Main(string[] args)
        {
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:開始");
         var m1 = AsyncMethod1();
         var m2 = AsyncMethod200ms();
         var m4 = AsyncMethod1000ms();
         m1.Wait();
         var m3 = AsyncMethod500ms(m1.Result);
         m2.Wait();
         m3.Wait();
         m4.Wait();
         var result = m1.Result + m2.Result + m3.Result + m4.Result;
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:最后得到的結果{result}");
         Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:結束");
         Console.ReadKey();
        }

        控制臺打印:

        2019-03-26 14:11:54 1154:開始
        2019-03-26 14:11:54 1154:我計算了一個值耗費200ms
        2019-03-26 14:11:54 1154:我做了一件耗費200ms的事情
        2019-03-26 14:11:55 1155:我做了一件耗費500ms的事情
        2019-03-26 14:11:55 1155:我做了一件耗費1000ms的事情
        2019-03-26 14:11:55 1155:最后得到的結果1203
        2019-03-26 14:11:55 1155:結束

        因為 AsyncMethod500ms() 依賴于 AsyncMethod1() 的返回結果作為參數,所以我們可以先直接以異步的方式運行 AsyncMethod1()AsyncMethod200ms()AsyncMethod1000ms() 三個方法,這個時候三個方法都會建立異步的子線程進行執行,但是后面的 AsyncMethod500ms() 想要執行,必須的有 AsyncMethod1() 的返回值,所以這個時候對 AsyncMethod1() 進行等待, 200ms 后, AsyncMethod1() 執行完成, m1.Wait() 等待結束,繼續執行 AsyncMethod500ms() ,并傳入了 AsyncMethod1() 的返回值 m1.Result ,最后因為需要對四個方法的返回值進行累加,所以在這之前必須保證其它三個方法也執行完成,所以需要分別對 AsyncMethod500ms()AsyncMethod200ms()AsyncMethod1000ms() 進行等待(Wait),因為此刻所有的方法都是異步執行的,所以程序的執行時間將≈執行時間最長的那個方法的執行時間( AsyncMethod1000ms() 執行 1000ms ,執行時間最長,程序的執行時間≈ 1000ms )。

        看完上面的內容,可以確定的是,在某些情況下,異步編程能夠很大的提高我們程序運行的效率,但是大家都在推崇的多使用異步編程不僅僅是因為軟件上面的原因,在硬件上也有著很大的原因。

        前段時間我們將原來跑在一臺辦公電腦的程序發布到一臺雙路E5的DELL的刀片機上面去,結果發現在DELL刀片機上面運行的性能竟然比之前的辦公電腦還差,開始我們懷疑是DELL刀片機使用的是虛擬機的問題,可能在某些地方沒有設置好,后來經過一系列的服務器性能測試,無論是CPU處理速度、磁盤IO還是網絡帶寬,DELL刀片機都遠超我們之前的那臺辦公電腦,但是我們運行的程序中的某個接口在效率上就是不如之前的辦公電腦!!!

        ???(直到后來的某一天,隨著我對.NET Core異步編程的理解的加深,終于明白是什么原因。)

        我們先來看一下我們日常開發使用的Intel CPU和服務器使用的CPU對比

        開發電腦CPU: 英特爾® 酷睿™ i5+8500 處理器

      1. 處理器基本頻率:3GHz
      2. 最大睿頻頻率:4.1GHz
      3. 內核數:六核心
      4. 線程數:六線程
      5. 服務器CPU: 英特爾® 至強® D-2177NT 處理器

      6. 處理器基本頻率:1.90 GHz
      7. 最大睿頻頻率:3.00 GHz
      8. 內核數:14
      9. 線程數:28
      10. 從上面的對比我們可以發現兩者之間的差異很明顯, i5 處理器的基本頻率和最大睿頻都高于服務器使用的 至強 處理器,但是在內核數量和線程數量上面卻遠遠不如 至強 ,如果我們的程序全部使用的同步編程的話,以WebApi為例,每一次請求中調用的方法都只是在CPU的某一個內核/線程中進行的,換句話說,CPU單核頻率的高低直接影響著同步方法的執行效率,而我們之前的程序幾乎都是使用了同步方法,在辦公電腦上的 i5 處理器和服務器使用的 至強 處理器的單核頻率的差異顯然就是之前性能問題的直接原因。

        并且鑒于服務器CPU的特性(單核頻率低,內核/線程數多),在程序中多使用異步/多線程的方式對于程序的性能而言是無容置疑的。

        注意:

        雖然異步編程很多時候能提升程序的效率,但不并意味著需要為了使用異步而將所有的方法改為異步執行,如果同步執行的開銷甚至比創建一個異步線程開銷還低的時候,就完全沒有必要再此處使用異步的方式。至于這其中的權衡利弊,或許需要一定的經驗才能拿捏的住。

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        在.NET Core中使用異步編程的方法步驟

        在.NET Core中使用異步編程的方法步驟:近期對于異步和多線程編程有些啟發,所以我決定把自己的理解寫下來。 思考:為什么要使用異步編程? 我們先看看同步方法和異步方法之前在程序中執行的邏輯: 1. 同步方法 static void Main(string[] args) { Console.WriteLine(${Dat
        推薦度:
        標簽: 中的 方法 方式
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 成人免费午夜在线观看| 免费观看美女用震蛋喷水的视频| 日本牲交大片免费观看| 亚洲xxxx18| 青青青青青青久久久免费观看| 亚洲精品自偷自拍无码| 好爽好紧好大的免费视频国产| 鲁死你资源站亚洲av| 四虎永久在线精品视频免费观看| 国产亚洲高清在线精品不卡| 免费在线观看你懂的| 亚欧洲精品在线视频免费观看| 亚洲人成图片小说网站| 1000部拍拍拍18勿入免费凤凰福利 | 亚洲国产天堂在线观看| 午夜免费1000部| 亚洲中文字幕久久精品蜜桃| 亚洲AV成人潮喷综合网| 中文字幕av免费专区| 91天堂素人精品系列全集亚洲| 无码日韩精品一区二区免费| 国产成人综合亚洲一区| 亚洲国产综合无码一区| 免费观看美女用震蛋喷水的视频 | 无码人妻一区二区三区免费n鬼沢 无码人妻一区二区三区免费看 | 99在线精品免费视频九九视| 亚洲欧洲无卡二区视頻| 亚洲中文字幕成人在线| 毛片无码免费无码播放| 亚洲第一街区偷拍街拍| 亚洲无线码一区二区三区| 亚洲黄色免费网站| 国产成人亚洲综合在线| 亚洲AV无码国产在丝袜线观看| 动漫黄网站免费永久在线观看 | 爱情岛亚洲论坛在线观看| 久久精品国产亚洲沈樵| 毛片a级毛片免费观看免下载| 一级毛片**免费看试看20分钟| 亚洲视频一区在线观看| 免费在线精品视频|