亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

關(guān)于C#中async/await的用法實例詳解

 更新時間:2023年02月08日 16:04:23   作者:程序員在職場  
這篇文章主要介紹了關(guān)于C#中async/await的用法,今天寫一個demo徹底搞明白async/await的用法,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

一直對c#中async/await的用法模模糊糊,不太清晰,今天寫了一下Demo徹底明確一下async/await的用法,以免因為對其不了解而對后期的業(yè)務(wù)產(chǎn)生影響(比如事務(wù)導(dǎo)致的鎖表等等)。

1. 首先,async/await一般是成對出現(xiàn)才有意義。其意義在于可以等待異步操作完成后繼續(xù)順序執(zhí)行,而不是異步操作還沒處理完成主線程就進(jìn)行了下一步。

假設(shè),我們現(xiàn)在要模擬簡單的下載場景,首先用戶點擊下載,那么就調(diào)用DownloadHandle方法(異步)進(jìn)行下載,然后通知用戶下載完成。其使用async/await的區(qū)別如下:

(1)使用async/await 的情況:

internal class Program
    {
        static void Main(string[] args)
        {
            DownloadHandle();
            Console.ReadLine();
        }
        /// <summary>
        /// 正常使用async/await時,符合正常的業(yè)務(wù)邏輯:
        /// 1. 通知用戶下載開始
        /// 2. 異步下載
        /// 3. 等待異步下載完成后給用戶提示下載完成
        /// </summary>
        public static async void DownloadHandle()
        {
            Console.WriteLine("下載開始!->主線程ID:" + Thread.CurrentThread.ManagedThreadId);
            await Download();
            Console.WriteLine("下載完成!->主線程ID:" + Thread.CurrentThread.ManagedThreadId);

        }
        /// <summary>
        /// 下載
        /// </summary>
        /// <returns></returns>
        public static Task Download()
        {
            return Task.Run(() =>
            {
                Console.WriteLine("下載線程ID:->" + Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine("10%");
                Console.WriteLine("30%");
                Console.WriteLine("50%");
                Console.WriteLine("60%");
                Console.WriteLine("80%");
                Console.WriteLine("99%");
                Console.WriteLine("100%");
            });
        }
    }

結(jié)果如下:

可以看到,即時下載使用了異步(線程ID不同也表明了當(dāng)前使用了異步),業(yè)務(wù)邏輯最終還是按照我們的需求,按順序正序執(zhí)行了。

(2)不使用async/await的情況:

internal class Program
    {
        static void Main(string[] args)
        {
            DownloadHandle();
            Console.ReadLine();
        }
        /// <summary>
        /// 不適用async/await時,則代碼執(zhí)行順序時混亂的,不符合業(yè)務(wù)邏輯:
        /// 1. 通知用戶下載開始
        /// 2. 提示下載完成
        /// 3. 開始下載
        /// </summary>
        public static void DownloadHandle()
        {
            Console.WriteLine("下載開始!->主線程ID:" + Thread.CurrentThread.ManagedThreadId);
            Download();
            Console.WriteLine("下載完成!->主線程ID:" + Thread.CurrentThread.ManagedThreadId);

        }
        /// <summary>
        /// 下載
        /// </summary>
        /// <returns></returns>
        public static Task Download()
        {
            return Task.Run(() =>
            {
                Console.WriteLine("下載線程ID:->" + Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine("10%");
                Console.WriteLine("30%");
                Console.WriteLine("50%");
                Console.WriteLine("60%");
                Console.WriteLine("80%");
                Console.WriteLine("99%");
                Console.WriteLine("100%");
            });
        }
    }

結(jié)果如下:

可以看到,代碼執(zhí)行順序混亂了,“下載完成” 跑到了 “下載線程ID” 前面去了,完全沒有按照我們預(yù)期的順序執(zhí)行。

2. 如果可以await的方法不進(jìn)行await,那將會怎樣呢?

(1)如果被調(diào)用的異步方法內(nèi)部使用了Task.Run,那結(jié)果可參考我們1中進(jìn)行講述的結(jié)果。開發(fā)者可根據(jù)實際需要來進(jìn)行調(diào)用,如果異步方法的調(diào)用結(jié)果與其上下文邏輯沒有嚴(yán)格的執(zhí)行要求,則可以不進(jìn)行await(比如記錄日志等等)。反之,則需要加await。

(2)如果被調(diào)用的異步方法內(nèi)部只是返回了Task.CompletedTask,即時使用了await/async實際上還是等于同步執(zhí)行,如下圖。

internal class Program
    {
        static void Main(string[] args)
        {
            DownloadHandle();
            Console.ReadLine();
        }
        /// <summary>
        /// 模擬下載
        /// </summary>
        public static async void DownloadHandle()
        {
            Console.WriteLine("下載開始!->主線程ID:" + Thread.CurrentThread.ManagedThreadId);
            await Download();
            Console.WriteLine("下載完成!->主線程ID:" + Thread.CurrentThread.ManagedThreadId);

        }
        /// <summary>
        /// 下載
        /// </summary>
        /// <returns></returns>
        public static Task Download()
        {
            Console.WriteLine("下載線程ID:->" + Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("10%");
            Console.WriteLine("30%");
            Console.WriteLine("50%");
            Console.WriteLine("60%");
            Console.WriteLine("80%");
            Console.WriteLine("99%");
            Console.WriteLine("100%");
            return Task.CompletedTask;
        }

結(jié)果如圖:

可以看到,即使DonwloadHandle方法使用了await/async,還是進(jìn)行了同步執(zhí)行,并沒有異步效果(可從所有線程ID相同看出)

3.小技巧: 異步方法的返回值類型一般都是Task或者Task<T>類型的,當(dāng)返回值為Task時(即方法的返回值類型為void),我們可以直接return Task.Run(()=>{})(以下第一段代碼),而不必awaitTask.Run(()=>{})(以下第二段代碼),這樣也可從一定程度上提高代碼執(zhí)行效率。

/// <summary>
        /// 下載
        /// </summary>
        /// <returns></returns>
        public static Task Download()
        {
            return Task.Run(() =>
            {
                Console.WriteLine("下載線程ID:->" + Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine("10%");
                Console.WriteLine("30%");
                Console.WriteLine("50%");
                Console.WriteLine("60%");
                Console.WriteLine("80%");
                Console.WriteLine("99%");
                Console.WriteLine("100%");
            });
        }
/// <summary>
        /// 下載
        /// </summary>
        /// <returns></returns>
        public static async Task Download()
        {
            await Task.Run(() =>
            {
                Console.WriteLine("下載線程ID:->" + Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine("10%");
                Console.WriteLine("30%");
                Console.WriteLine("50%");
                Console.WriteLine("60%");
                Console.WriteLine("80%");
                Console.WriteLine("99%");
                Console.WriteLine("100%");
            });
        }

到此這篇關(guān)于關(guān)于C#中async/await的用法的文章就介紹到這了,更多相關(guān)C#中async/await的用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#異步編程async/await用法詳解

    C#異步編程async/await用法詳解

    本文詳細(xì)講解了C#異步編程async/await的用法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01
  • c#在sql中存取圖片image示例

    c#在sql中存取圖片image示例

    這篇文章主要介紹了c#在sql中存取圖片image示例,需要的朋友可以參考下
    2014-03-03
  • C#數(shù)據(jù)庫連接方式(類的形式)

    C#數(shù)據(jù)庫連接方式(類的形式)

    這篇文章主要介紹了C#數(shù)據(jù)庫連接方式(類的形式),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • C#實現(xiàn)修改系統(tǒng)時間的方法

    C#實現(xiàn)修改系統(tǒng)時間的方法

    這篇文章主要介紹了C#實現(xiàn)修改系統(tǒng)時間的方法,是一個非常實用的功能,需要的朋友可以參考下
    2014-07-07
  • C#動態(tài)創(chuàng)建Access數(shù)據(jù)庫及表的方法

    C#動態(tài)創(chuàng)建Access數(shù)據(jù)庫及表的方法

    這篇文章主要介紹了C#動態(tài)創(chuàng)建Access數(shù)據(jù)庫及表的方法,以實例形式分析了創(chuàng)建access數(shù)據(jù)庫及在access數(shù)據(jù)庫中建表的完整過程,是非常實用的技巧,需要的朋友可以參考下
    2014-12-12
  • 使用Deflate算法對文件進(jìn)行壓縮與解壓縮的方法詳解

    使用Deflate算法對文件進(jìn)行壓縮與解壓縮的方法詳解

    本篇文章是對使用Deflate算法對文件進(jìn)行壓縮和解壓縮的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • C#實現(xiàn)微信結(jié)合百度api獲取當(dāng)前用戶地理位置的方法

    C#實現(xiàn)微信結(jié)合百度api獲取當(dāng)前用戶地理位置的方法

    這篇文章主要介紹了C#實現(xiàn)微信結(jié)合百度api獲取當(dāng)前用戶地理位置的方法,結(jié)合實例形式分析了C#調(diào)用微信與百度API接口的相關(guān)操作技巧,需要的朋友可以參考下
    2017-07-07
  • c#實現(xiàn)一個超實用的證件照換底色小工具(附源碼)

    c#實現(xiàn)一個超實用的證件照換底色小工具(附源碼)

    這篇文章主要給大家介紹了關(guān)于利用c#實現(xiàn)一個超實用的證件照換底色小工具的相關(guān)資料,通過這個小工具大家可以很方便的進(jìn)行底色的切換,不用再因為底色的原因頭疼了,需要的朋友可以參考借鑒,下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • Unity實現(xiàn)俄羅斯方塊(三)

    Unity實現(xiàn)俄羅斯方塊(三)

    這篇文章主要為大家詳細(xì)介紹了Unity實現(xiàn)俄羅斯方塊的第一部分代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • WPF中TreeView控件的用法

    WPF中TreeView控件的用法

    這篇文章介紹了WPF中TreeView控件的用法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06

最新評論