1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        .NET異步和多線程系列(六)- async/await

        共 5298字,需瀏覽 11分鐘

         ·

        2020-09-12 19:50

        本文是.NET異步和多線程系列的第六章,本章主要對之前介紹過的async/await做一些補(bǔ)充說明。

        下面我們直接來看下代碼和運(yùn)行結(jié)果:

        using System;
        using System.Threading;
        using System.Threading.Tasks;

        namespace MyAsyncAwait
        {
        ///
        /// await/async 是C#保留關(guān)鍵字,通常是成對出現(xiàn),語法糖。
        ///
        /// 主線程調(diào)用async/await方法,主線程遇到await返回執(zhí)行后續(xù)動作,
        /// await后面的代碼會等著Task任務(wù)的完成后再繼續(xù)執(zhí)行
        /// 其實(shí)就像把a(bǔ)wait后面的代碼包裝成一個ContinueWith的回調(diào)動作
        /// 然后這個回調(diào)動作可能是Task線程,也可能是新的子線程,也可能是主線程
        ///
        /// 一個async方法,如果沒有返回值,可以方法聲明返回Task
        /// await/async能夠用同步的方式編寫代碼,但又是非阻塞的。
        ///
        /// async方法在編譯后會生成一個狀態(tài)機(jī)(實(shí)現(xiàn)了IAsyncStateMachine接口)
        ///

        class Program
        {
        static void Main(string[] args)
        {
        Console.WriteLine($
        "當(dāng)前主線程開始 ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
        AwaitAsyncClass.TestShow();
        Console.WriteLine($
        "當(dāng)前主線程結(jié)束 ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
        Console.ReadKey();
        }
        }

        ///
        /// await/async關(guān)鍵字 語法糖
        /// await/async 要么不用 要么用到底
        ///

        public class AwaitAsyncClass
        {
        public static void TestShow()
        {
        Test();
        }

        private async static Task Test()
        {
        Console.WriteLine($
        "Test開始 ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");

        Task
        <long> t = SumAsync();
        Console.WriteLine($
        "遇到await主線程回來干活了 ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");

        {
        long lResult = await t; //await后面的代碼會由線程池的線程執(zhí)行,非阻塞。
        Console.WriteLine($"最終得到的lResult={lResult}");
        }

        {
        //t.Wait(); //主線程等待Task的完成,阻塞的
        //long lResult = t.Result; //訪問Result,主線程等待Task的完成,阻塞的,效果跟t.Wait()一樣
        //Console.WriteLine($"最終得到的lResult={lResult}");
        }

        Console.WriteLine($
        "Test結(jié)束 ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
        }

        ///
        /// 帶返回值的Task
        /// 要使用返回值就一定要等子線程計算完畢
        ///

        private static async Task<long> SumAsync()
        {
        Console.WriteLine($
        "SumAsync start ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
        long result = 0;

        //await后面的代碼會等著Task任務(wù)的完成后再繼續(xù)執(zhí)行
        //其實(shí)就像把a(bǔ)wait后面的代碼包裝成一個ContinueWith的回調(diào)動作
        //然后這個回調(diào)動作可能是Task線程,也可能是新的子線程,也可能是主線程
        await Task.Run(() =>
        {
        for (int k = 0; k < 2; k++)
        {
        Console.WriteLine($
        "SumAsync 第1個 await Task.Run k={k} ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
        Thread.Sleep(
        1000);
        }
        for (long i = 0; i < 999_999_999; i++)
        {
        result
        += i;
        }
        });

        Console.WriteLine($
        "SumAsync 第1個 await Task.Run的后續(xù)任務(wù)開始 ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
        await Task.Run(() =>
        {
        for (int k = 0; k < 2; k++)
        {
        Console.WriteLine($
        "SumAsync 第2個 await Task.Run k={k} ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
        Thread.Sleep(
        1000);
        }
        for (long i = 0; i < 999_999_999; i++)
        {
        result
        += i;
        }
        });

        Console.WriteLine($
        "SumAsync 第2個 await Task.Run的后續(xù)任務(wù)開始 ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
        await Task.Run(() =>
        {
        for (int k = 0; k < 2; k++)
        {
        Console.WriteLine($
        "SumAsync 第3個 await Task.Run k={k} ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
        Thread.Sleep(
        1000);
        }
        for (long i = 0; i < 999_999_999; i++)
        {
        result
        += i;
        }
        });

        Console.WriteLine($
        "SumAsync end ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
        return result;
        }
        }
        }

        運(yùn)行結(jié)果如下:

        仔細(xì)觀察結(jié)果會發(fā)現(xiàn)

          主線程調(diào)用async/await方法,主線程遇到await后會返回執(zhí)行后續(xù)動作;

          await后面的代碼會等著Task任務(wù)的完成后再繼續(xù)執(zhí)行,其實(shí)就像把a(bǔ)wait后面的代碼包裝成一個ContinueWith的回調(diào)動作;

          然后這個回調(diào)動作可能是Task線程,也可能是新的子線程,也可能是主線程;

          await/async能夠用同步的方式編寫代碼,但又是非阻塞的。

        下面我們調(diào)整下Test方法后再運(yùn)行(紅色的為調(diào)整部分):

        private async static Task Test()
        {
        Console.WriteLine($
        "Test開始 ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");

        Task
        <long> t = SumAsync();
        Console.WriteLine($
        "遇到await主線程回來干活了 ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");

        {
        //long lResult = await t; //await后面的代碼會由線程池的線程執(zhí)行,非阻塞。
        //Console.WriteLine($"最終得到的lResult={lResult}");

        }

        {
        //t.Wait(); //主線程等待Task的完成,阻塞的
        long lResult = t.Result; //訪問Result,主線程等待Task的完成,阻塞的,效果跟t.Wait()一樣
        Console.WriteLine($"最終得到的lResult={lResult}"
        );
        }

        Console.WriteLine($
        "Test結(jié)束 ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
        }

        調(diào)整后運(yùn)行結(jié)果如下:

        仔細(xì)觀察結(jié)果會發(fā)現(xiàn)

          訪問Result,主線程會等待Task的完成,阻塞的。

        其實(shí)async方法在編譯后會生成一個狀態(tài)機(jī)(實(shí)現(xiàn)了IAsyncStateMachine接口),有興趣的可以自行去了解下。

        至此本文就介紹完了,有興趣的還可以看下我之前寫過一篇也是關(guān)于async/await的文章:https://www.cnblogs.com/xyh9039/p/11391507.html

        ?

        Demo源碼:

        鏈接:https://pan.baidu.com/s/1jnG5IpteuKCdmF6-tr--cA
        提取碼:3onm

        此文由博主精心撰寫轉(zhuǎn)載請保留此原文鏈接:https://www.cnblogs.com/xyh9039/p/13622122.html

        版權(quán)聲明:如有雷同純屬巧合,如有侵權(quán)請及時聯(lián)系本人修改,謝謝?。?!

        版權(quán)申明:本文來源于網(wǎng)友收集或網(wǎng)友提供,如果有侵權(quán),請轉(zhuǎn)告版主或者留言,本公眾號立即刪除。


        瀏覽 61
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            91成熟丰满女人少妇777 sm调教小sao货叫主人语录 | 日韩一区二区三区视频 | 久久久噜噜噜久久 | 美女干逼视频 | 香蕉成人在线视频 | 女配穿书病娇被强啪h | 日韩在线小视频 | 古装男女圆房做爰视频 | 国产精品久久久久久久久免费看 | 人人人人人人操 |