欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#中async和await的深入分析

 更新時(shí)間:2022年11月09日 11:03:02   作者:code?bean  
Async/Await是C# 5引入的關(guān)鍵字,用以提高用戶界面響應(yīng)能力和對(duì)Web資源的訪問能力,同時(shí)它使異步代碼的編寫變得更加容易,下面這篇文章主要給大家介紹了關(guān)于C#中async和await的相關(guān)資料,需要的朋友可以參考下

大概理解

查了一個(gè)小時(shí)的資料:async和await

發(fā)現(xiàn)這個(gè)大神的解釋一針見血,深得我心!以最簡(jiǎn)單的例子,解釋了async和await。妙~~~

大多情況下,分開才能體現(xiàn)async和await的價(jià)值!

 但,await 并沒有這么簡(jiǎn)單。

深入分析

await和Wait()的區(qū)別

接下來繼續(xù)往下看:

await Task.Delay(3000);  和Task.Delay(3000).Wait();   有沒有區(qū)別?

上代碼:

using System.Diagnostics;
 
namespace await_async2
{
    internal class Program
    {
 
        static  public void TestWait()
        {
            var t = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Start");
                Task.Delay(3000).Wait();
                Console.WriteLine("Done");
            });
            t.Wait();
            Console.WriteLine("All done");
        }
 
 
        static public void TestWait2()
        {
            var t = Task.Factory.StartNew(async () =>
            {
                Console.WriteLine("Start");
                await Task.Delay(3000);
                Console.WriteLine("Done");
            });
            t.Wait();
            Console.WriteLine("All done");
        }
 
        static public void TestWait3()
        {
            var t = Task.Run(async () =>
            {
                Console.WriteLine("Start");
                await Task.Delay(3000);
                Console.WriteLine("Done");
            });
            t.Wait();
            Console.WriteLine("All done");
        }
 
        static void Main(string[] args)
        {
            TestWait2();
            //避免程序提前退出,導(dǎo)致一些現(xiàn)象看不到
            Task.Delay(5000).Wait();
        }
    }
}

首先,強(qiáng)調(diào)一下,最后一句 Task.Delay(5000).Wait(); 是必須的,不然,程序提前退出,導(dǎo)致一些現(xiàn)象看不到,從而蒙蔽了我們。

第1段代碼TestWait執(zhí)行效果,如下:

第2段代碼TestWait2執(zhí)行效果,如下:

第3段代碼TestWait3執(zhí)行效果,如下:

現(xiàn)在給出結(jié)論:

Task.Delay(3000).Wait(); 這個(gè)就是同步等。

await Task.Delay(3000); 因?yàn)闆]有分開來寫(見第一張圖),所以基本和同步等沒有區(qū)別。

但是如果 await Task.Delay(3000); 是寫到:Task.Factory.StartNew里面的

static public void TestWait2()
        {
            var t = Task.Factory.StartNew(async () =>
            {
                Console.WriteLine("Start");
                await Task.Delay(3000);
                Console.WriteLine("Done");
            });
            t.Wait();
            Console.WriteLine("All done");
        }

那這個(gè)效果不一樣了,他們執(zhí)行的權(quán)限丟出去了有點(diǎn)像python里的yeild,來看下程序的執(zhí)行順序:

 這里就看出了:await Task.Delay(3000);  和Task.Delay(3000).Wait(); 的區(qū)別了。(但是這種情況如果在道Task.Run里面就體現(xiàn)不出來?。?/p>

然后,我有簡(jiǎn)單做了一個(gè)實(shí)驗(yàn):

這就更明了了, await Task.Delay(3000); 就像設(shè)置了一個(gè)回調(diào),一旦三秒時(shí)間一到,程序的指針就會(huì)回到await Task.Delay(3000);后面的位置,直到函數(shù)執(zhí)行結(jié)束。再回到之前的位置。這就是所謂的用同步的方式寫異步的代碼吧

但是,為啥在Task.Factory.StartNew才會(huì)體現(xiàn)出來,這個(gè)我就不清楚了,請(qǐng)各位大佬指點(diǎn)一下。

去掉Task.Run的Wait

再來對(duì)比一下,下面這兩個(gè)函數(shù):

 static public void TestWait8()
 {
     var t = Task.Run(async () =>
     {
         Console.WriteLine("Start");
         await Task.Delay(3000);
         Console.WriteLine("Done");
     });
     Console.WriteLine("All done");
 }
 static public void TestWait8_5()
 {
     var t = Task.Factory.StartNew(async () =>
     {
         Console.WriteLine("Start");
         await Task.Delay(3000);
         Console.WriteLine("Done");
     });
     t.Wait();
     Console.WriteLine("All done");
 }

先看第一個(gè)TestWait8,由于Task.Run不再調(diào)用 t.Wait(),Task.Run內(nèi)部這個(gè)線程主線程是并行的關(guān)系。程序指針會(huì)在兩個(gè)線程中來回切換。如果一方中寫了await xxx,那程序指針必然跳到另一個(gè)線程。直達(dá)await結(jié)束才可能返回。 這種情形是比較多的。此時(shí)await能節(jié)省大量等待時(shí)間(比如IO操作時(shí)間),充分利用等待時(shí)間。

此時(shí) Console.WriteLine("All done");會(huì)最先被打印出來。

再看第二個(gè)TestWait8_5(其實(shí)就是回顧一下),當(dāng)程序執(zhí)行到t.Wait()時(shí),程序不會(huì)繼續(xù)向下了,(此時(shí)因?yàn)橛衪.Wait()的存在,所以子線程其實(shí)是優(yōu)先于主線程的)而是進(jìn)入到子線程的內(nèi)部進(jìn)程,試圖將這個(gè)線程執(zhí)行完,但是再線程里面遇到又遇到await Task.Delay(3000);此時(shí)程序指針不會(huì)再這里死等,程序指針又跳回主線程繼續(xù)執(zhí)行,直到三秒到了之后就會(huì)回到子線程,子線程執(zhí)行完了之后,再回到主線程。

但是如果吧TestWait8_5 中    Task.Factory.StartNew 換成 Task.Run ,那么前面的過程一樣,只是執(zhí)行到await Task.Delay(3000);時(shí)候,此時(shí)會(huì)死等,不會(huì)跳到主線程,而是一定等到這個(gè)子線程完結(jié),再回主線程。

小結(jié)

總結(jié)一下就是,遇到await 一定會(huì)等,至于程序指針是先跳到其他線程,還是在此線程死等,就看你的線程函數(shù)這么寫的了。

其他

.Await();

最后,還有個(gè):Task.Delay(3000).Await();

這個(gè)是prsim對(duì)Task寫的的一個(gè)拓展方法(避免在主線程調(diào)用時(shí),阻塞UI):

總結(jié)

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

相關(guān)文章

  • C#溫故而知新系列教程之閉包

    C#溫故而知新系列教程之閉包

    閉包是將一些執(zhí)行語句的封裝,可以將封裝的結(jié)果像對(duì)象一樣傳遞,在傳遞時(shí),這個(gè)封裝依然能夠訪問到原上下文。下面這篇文章主要給大家介紹了關(guān)于C#中閉包的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-05-05
  • C#中的in參數(shù)與性能分析詳解

    C#中的in參數(shù)與性能分析詳解

    這篇文章主要給大家介紹了關(guān)于C#中in參數(shù)與性能分析的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • C#圖表算法之最短路徑

    C#圖表算法之最短路徑

    本文詳細(xì)講解了C#圖表算法之最短路徑,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • Unity3D撤回命令開發(fā)詳解

    Unity3D撤回命令開發(fā)詳解

    這篇文章主要為大家詳細(xì)介紹了Unity3D撤回命令開發(fā),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • WPF實(shí)現(xiàn)3D翻牌式倒計(jì)時(shí)特效

    WPF實(shí)現(xiàn)3D翻牌式倒計(jì)時(shí)特效

    這篇文章主要為大家詳細(xì)介紹了WPF實(shí)現(xiàn)3D翻牌式倒計(jì)時(shí)特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • C#實(shí)現(xiàn)的微信網(wǎng)頁授權(quán)操作邏輯封裝示例

    C#實(shí)現(xiàn)的微信網(wǎng)頁授權(quán)操作邏輯封裝示例

    這篇文章主要介紹了C#實(shí)現(xiàn)的微信網(wǎng)頁授權(quán)操作邏輯封裝,分析了微信網(wǎng)頁授權(quán)操作的原理、步驟并給出了C#實(shí)現(xiàn)的網(wǎng)頁授權(quán)操作邏輯封裝類,需要的朋友可以參考下
    2016-10-10
  • 基于C#動(dòng)手實(shí)現(xiàn)網(wǎng)絡(luò)服務(wù)器Web Server

    基于C#動(dòng)手實(shí)現(xiàn)網(wǎng)絡(luò)服務(wù)器Web Server

    這篇文章主要為大家詳細(xì)介紹了基于C#動(dòng)手實(shí)現(xiàn)網(wǎng)絡(luò)服務(wù)器Web Server,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • C#編程實(shí)現(xiàn)DataTable添加行的方法

    C#編程實(shí)現(xiàn)DataTable添加行的方法

    這篇文章主要介紹了C#編程實(shí)現(xiàn)DataTable添加行的方法,結(jié)合兩個(gè)實(shí)例形式分析了C#操作DataTable實(shí)現(xiàn)動(dòng)態(tài)添加行的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • 在C#語言里對(duì)NULL的技術(shù)處理小結(jié)

    在C#語言里對(duì)NULL的技術(shù)處理小結(jié)

    在 C# 中處理 null 值是編寫可靠且可靠的代碼的一個(gè)重要方面,在本文中,我將討論一些在 C# 中處理 null 值的最常用技術(shù),感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • DevExpress實(shí)現(xiàn)根據(jù)行,列索引來獲取RepositoryItem的方法

    DevExpress實(shí)現(xiàn)根據(jù)行,列索引來獲取RepositoryItem的方法

    這篇文章主要介紹了DevExpress實(shí)現(xiàn)根據(jù)行,列索引來獲取RepositoryItem的方法,需要的朋友可以參考下
    2014-08-08

最新評(píng)論