<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Task.Yeild的探究

            在與同事討論async/await內部實現的時候,突然想到Task.Yeild()這個函數,為什么呢,了解一點C#async/await內部機制的都知道,在await一個異步任務(函數)的時候,它會先判斷該Task是否已經完成,如果已經完成,則繼續執行下去,不會返回到調用方,原因是盡量避免線程切換,因為await后面部分的代碼很可能是另一個不同的線程執行,而Task.Yeild()則可以強制回到調用方,或者說主動讓出執行權,給其他Task執行的機會,可以把Task理解為協程,Task.Yeild()和Thread.sleep(0)有點相同。

            為了證明我的結論成立,請看代碼:

      public static async Task Test1()
      {
           await Task.CompletedTask;
           Thread.Sleep(1000);
           Console.WriteLine("Test1任務完成");
      }

      public static async Task Test2()
      {
           await Task.Delay(1);
           Thread.Sleep(1000);
           Console.WriteLine("Test2任務完成");
      }

      public static async Task Test3()
      {
           await Task.Yield();
           Thread.Sleep(1000);
           Console.WriteLine("Test3任務完成");
      }

      static void Main(string[] args)
      {
           Console.WriteLine(DateTime.Now);
           _ = Test1();
           Console.WriteLine(DateTime.Now);
           Console.ReadLine();
      }

            按照開頭的理論,Test1()異步函數由于await了一個已經完成的任務,所以會繼續往下執行,阻塞1秒鐘,然后回到調用方,打印的時間之差會相隔一秒。

      image

            Test2()異步函數由于await了一個未完成的任務(1ms對于CPU來說是很長的了),所以會返回調用方,然后打印相同的時間,一秒鐘之后會打印執行完畢。

      image

            Test3()調用了Task.Yeild()函數,主動讓出執行權,所以會直接返回調用方,然后打印相同的時間,一秒之后會打印執行完畢。

      image

            可以看到,開頭的結論是正確的。那么,有什么意義呢?Yeild的意思在這里其實就是退讓,讓出的意思,讓出什么呢?就是讓出執行權,這與Thread.sleep(0)讓出CPU執行權給其他線程(前提是有其他線程競爭)有機會執行是一個道理。

            請看我的例子:

      public static async Task OP1()
      {
           while (true)
           {
               await Task.Yield();//這里會捕捉同步上下文,由于是控制臺程序,沒有同步上下文,所以默認的線程池任務調度器變成同步上下文
                                           //也就是說后面的代碼將會在線程池上執行,由于線程池工作線程數量設置為1,所以必須主動讓出執行權,讓其他的
                                           //任務有執行的機會
               Console.WriteLine("OP1在執行");
               Thread.Sleep(1000);//模擬一些需要占用CPU的操作
           }
      }

      public static async Task OP2()
      {
           while (true)
           {
               await Task.Yield();
               Console.WriteLine("OP2在執行");
               Thread.Sleep(1000);
           }
      }
      static async Task Main(string[] args)
      {
           ThreadPool.SetMinThreads(1, 1);
           ThreadPool.SetMaxThreads(1, 1);
           //Task.Run()方法默認使用線程池任務調度器執行任務,由于主線程不是線程池線程,所以使用Task.Run()
           var t = Task.Run(async () =>
           {
               var t1 = OP1();
               var t2 = OP2();
               await Task.WhenAll(t1, t2);
           });
           await t;
           Console.ReadLine();
      }

      image

            可以看出OP1()和OP2()兩個協程(Task)互相爭用一個線程(用戶模式下的CPU),如果不主動讓出執行權,另一個協程(Task)將不會有機會執行。

            例如:

      public static async Task OP2()
      {
           while (true)
           {
               await Task.CompletedTask;//或者是直接去掉
               Console.WriteLine($"OP2在執行 {DateTime.Now}");
               Thread.Sleep(1000);
           }
      }

            這樣OP1()將永遠不會有機會執行。

      image

      posted @ 2020-07-09 00:44  白煙染黑墨  閱讀(115)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 在线观看视频一区二区三区| 无码一区二区三区久久精品| 太谷县| 99人中文字幕亚洲区三| 国产又爽又黄的激情视频| 久久天堂综合亚洲伊人HD妓女| 99在线视频免费观看| 九九色这里只有精品国产| 国产精品天干天干综合网| 亚洲大尺度无码专区尤物| 风韵丰满熟妇啪啪区老熟熟女| 久久先锋男人AV资源网站| 诏安县| 久久久久亚洲精品无码系列| 亚洲精品成人福利网站| 福利成人午夜国产一区| 日韩成人午夜精品久久高潮| 国产午夜精品福利91| 日本高清aⅴ毛片免费| 国内揄拍国内精品对久久| 欧美成本人视频免费播放| 日韩一区二区三区无码影院| 伦理片午夜视频在线观看| 开心一区二区三区激情| 国产在线视频www色| 女同亚洲精品一区二区三| 亚洲综合一区国产精品| 亚洲国产理论片在线播放| 色爱av综合网国产精品| 一区二区三区不卡国产| 人人色在线视频播放| 精品偷自拍另类精品在线| 国产永久免费高清在线| 94人妻少妇偷人精品| 成人网站免费观看永久视频下载 | 野外做受三级视频| 日本高清在线观看WWW色| 日韩不卡在线观看视频不卡| 花式道具play高h文调教| 国产精品综合一区二区三区| 一本色道久久综合熟妇人妻|