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

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

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

      Csharper Async和Await

      Async和Await的學習

      AsyncAwait語法解讀

      它是一個語法糖:編譯器提供的便捷功能
      async 是用來修飾方法,如果單獨出現,方法會警告,沒有什么作用
      await在方法體內部,只能放在async修飾的方法內,必須放在task前面
      async/await方法里面如果沒有返回值,默認返回一個Task,或者void(推薦用Task,而不是void,因為這樣才能await/wait)
      帶async+await后,返回值要多一層Task<>

      不使用await/async的代碼進行運行

          public static void TestShow()
          {
              Test();
          }
      
      
          public static void Test()
          {
              Console.WriteLine($"當前主線程id={Thread.CurrentThread.ManagedThreadId.ToString("00")}");
              {
                  NoReturnNoAwait();
              }
      
              Console.WriteLine($"Main Thread Task ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
              Console.Read();
          }
      
          private static async void NoReturnNoAwait()
          {
              //主線程執行
              Task task = Task.Run(() =>//啟動新線程完成任務
              {
                  Thread.Sleep(1000);
                  Console.WriteLine($"NoReturnNoAwait Sleep3000 before,ThreadId={Thread.CurrentThread.ManagedThreadId}");
                  Thread.Sleep(1000);
                  Console.WriteLine($"NoReturnNoAwait Sleep3000 after,ThreadId={Thread.CurrentThread.ManagedThreadId}");
              });
      
              //主線程執行
              Console.WriteLine($"NoReturnNoAwait Sleep after Task,ThreadId={Thread.CurrentThread.ManagedThreadId}");
          }
      }
      

      運行后的結果

      運行另外一個函數并不適用async:

         public static void Test()
         {
             //Console.WriteLine($"當前主線程id={Thread.CurrentThread.ManagedThreadId.ToString("00")}");
             //{
             //     NoReturnNoAwait();
             //}
      
             {
                 Task t = NoReturn();
                 t.Wait();//主線程在這里就可以登錄
                 {
                     for (int i = 0; i < 10; i++)
                     {
                         Thread.Sleep(300);
                         Console.WriteLine($"Main Thread Task ManagedThreadId={Thread.CurrentThread.ManagedThreadId.ToString("00")} i={i}");
                     }
                 }
             }
      }
      
      
       private static Task NoReturn()
       {
           //主線程執行
           Console.WriteLine($"NoReturn Sleep before await,ThreadId={Thread.CurrentThread.ManagedThreadId}");
           TaskFactory taskFactory = new TaskFactory();
           Task task = taskFactory.StartNew(() =>
           {
               Console.WriteLine($"NoReturn Sleep3000 before,ThreadId={Thread.CurrentThread.ManagedThreadId}");
               Thread.Sleep(3000);
               Console.WriteLine($"NoReturn Sleep3000 after,ThreadId={Thread.CurrentThread.ManagedThreadId}");
           });
      
           //像什么?continuwith
      
           //task.ContinueWith(t =>
           //{
           //    Console.WriteLine($"NoReturn Sleep after await,ThreadId={Thread.CurrentThread.ManagedThreadId}");
           //});
      
           return task;
      }
      

      使用async和await關鍵字的方法

       public static void Test()
       {
               {
               Task t = NoReturnTask();
               Console.WriteLine($"Main Thread Task ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
      }
      }
      
        private static async Task NoReturnTask() //在async/await方法里面如果沒有返回值,默認返回一個Task
        {
            //這里還是主線程的id
            Console.WriteLine($"NoReturnTask Sleep before await,ThreadId={Thread.CurrentThread.ManagedThreadId}");
      
            Task task = Task.Run(() =>
            {
                Console.WriteLine($"NoReturnTask Sleep3000 before,ThreadId={Thread.CurrentThread.ManagedThreadId}");
                Thread.Sleep(1000);
                Console.WriteLine($"NoReturnTask Sleep3000 after,ThreadId={Thread.CurrentThread.ManagedThreadId}");
            });
            await task;
            Console.WriteLine($"NoReturnTask Sleep after await,ThreadId={Thread.CurrentThread.ManagedThreadId}");
      }
      

      可以觀察到我們的代碼都是并行的。

      1. await: 線程遇到awai就返回,不阻塞:并發執行
      2. 做到控制順序
        其實就是以寫同步方法 的方式;來完成多線程:--可以控制順序
      3. 主線程和子線程是并發執行
      4. 有點類似于一個回調
      5. 有async/await 如果沒有返回值,就直接返回一個Task

      特點:
      l. 可以多線程并發執行,可以控制代碼的執行順序一一做到了嚴格控制代碼的執行順序;
      2.執行的特點:當前執行的線程,調用的有asyncawait修飾的函數,且沒有await修飾,進入函數后,遇到await,就直接返回執行調用當前函數后面的代碼:如果當前調用也用了await修飾,就嚴格按照順序執行:不存在遇到await回去繼續往后執行:
      3.await啟動線程的后面的內容,又會啟動一個新的線程來繼續往后執行;以此往復;

      AsyncAwait底層源碼解讀(狀態機)

      async和await在底層是一個狀態機(狀態模式),類似紅綠燈,紅燈:停,綠燈:行,按照條件執行,像switch

      示例代碼

       public class AwaitAsyncILSpy
       {
           public static void Show()
           {
               Console.WriteLine($"start1 {Thread.CurrentThread.ManagedThreadId.ToString("00")}");
               Async();
               Console.WriteLine($"aaa2 {Thread.CurrentThread.ManagedThreadId.ToString("00")}");
           }
           public static async void Async()
           {
               Console.WriteLine($"ddd5 {Thread.CurrentThread.ManagedThreadId.ToString("00")}");
               await Task.Run(() =>
               {
                   Thread.Sleep(500);
                   Console.WriteLine($"bbb3 {Thread.CurrentThread.ManagedThreadId.ToString("00")}");
               });
               Console.WriteLine($"ccc4 {Thread.CurrentThread.ManagedThreadId.ToString("00")}");
           }
       }
      
      

      使用Ilspy反編譯以后

      看到IL反匯編出來的代碼,我們可以知道:

      1. 實例化狀態機
      2. 把狀態機實例交給一個build去執行
      3. 整理線程的上下文
      4. stateMachine.MoveNext(); 調用MoveNext方法
      5. MoveNext如何執行:先獲取一個狀態 ---繼續往后執行
      6. 如果有異常---一拋出異常--把狀態重置為-2
      7. 如果沒有異常,把狀態重置重置為-2
      8. SetResult();---把結果包裹成一個Tsak

      Winform中使用async/await

      這里創建一個winform的程序并實現了2個按鈕

      同步按鈕得代碼:

       private void btnSync_Click(object sender, EventArgs e)
       {
           Debug.WriteLine($"**********************************btnSync_Click******************************************");
           Debug.WriteLine($"This is btnSync_Click Start,ThreadId={Thread.CurrentThread.ManagedThreadId}");
           var task = this.CalculationAsync(1_000_000);           
         
           long lResult = task.Result;      
      
           Debug.WriteLine($"This is btnSync_Click   End,ThreadId={Thread.CurrentThread.ManagedThreadId}");
      
           this.textSync.Text = lResult.ToString();
       }
      

      異步按鈕得代碼:

       /// <summary>
       ///異步方法: 正常執行
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       private async void btnAsync_Click(object sender, EventArgs e)
       {
           Debug.WriteLine($"**********************************btnAsync_Click******************************************");
           Debug.WriteLine($"This is btnAsync_Click Start,ThreadId={Thread.CurrentThread.ManagedThreadId}");
      
           long lResult = await this.CalculationAsync(1_000_000);
      
           Debug.WriteLine($"This is btnAsync_Click   End,ThreadId={Thread.CurrentThread.ManagedThreadId}");
      
           this.textAsyncResult.Text = lResult.ToString();
        
       }
      

      對應計算得代碼:

       private async Task<long> CalculationAsync(long total)
       {
           var task = await Task.Run(() =>
             {
                 Debug.WriteLine($"This is CalculationAsync Start,ThreadId={Thread.CurrentThread.ManagedThreadId}");
                 long lResult = 0;
                 for (int i = 0; i < total; i++)
                 {
                     lResult += i;
                 }
                 Debug.WriteLine($"This is CalculationAsync   End,ThreadId={Thread.CurrentThread.ManagedThreadId}");
      
                 return lResult;
             });
      
           return task; 
       }
      

      當點擊同步按鈕得時候就會遇到一個問題,程序卡死了,為什么會造成這個問題?

      1. 主線程要等待 Winform特殊設計:await后面的內容必須由主線程執行;
      2. 主線程在這兒也等待著在
      3. 主線程無暇分身導致死鎖

      更改控件的值,這里必須是(UI線程)主線程去執行;
      每次執行都能成功,說明每次這里都是主線程來執行的;
      跟Winform設計有關系;在Winform中,await后面的內容,都會讓主線程來執行;

      因此造成了主線程得死鎖。

      posted @ 2024-07-25 17:47  飄雨的河  閱讀(94)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 精品国产av最大网站| 无码免费大香伊蕉在人线国产| 亚洲成在人线AⅤ中文字幕| 国产精品午夜av福利| 国产一区二区日韩在线| 无码熟妇人妻AV在线影片最多| 激情综合网激情综合网五月| av色蜜桃一区二区三区| 国产日韩综合av在线| 少妇的丰满3中文字幕| 女人香蕉久久毛毛片精品| 99热这里只有精品免费播放| 简阳市| 色噜噜亚洲男人的天堂| 国产 一区二区三区视频| 日日躁夜夜躁狠狠躁超碰97| 精品久久人人妻人人做精品| 国精品无码一区二区三区在线看| 亚洲中文字幕一二三四区| 伊人久久大香线蕉av一区二区| 男人扒开添女人下部免费视频| 色av专区无码影音先锋| 欧美 喷水 xxxx| 社旗县| av中文无码乱人伦在线观看| 欧美成本人视频免费播放| 亚洲欧洲日韩精品在线| 国产女人看国产在线女人| jizz国产免费观看| 少妇粗大进出白浆嘿嘿视频| 枞阳县| 中文熟妇人妻av在线| 日本道精品一区二区三区| 中文字幕在线国产精品| 久久精品国产精品第一区| 女高中生强奷系列在线播放| 亚洲三区在线观看无套内射| 国产老熟女一区二区三区| 夜鲁鲁鲁夜夜综合视频| 中国老太婆video| 国产午夜一区二区在线观看|