C#進(jìn)階之Async await異步編程

前言

自從C# 5.0時代引入async和await關(guān)鍵字后,異步編程就變得流行起來唆缴。尤其在現(xiàn)在的.NET Core時代奴饮,甚至如果你的代碼中沒有出現(xiàn)async或者await關(guān)鍵字,都會讓人感覺到很奇怪缝龄。
本篇文章將會先給大家?guī)硪粋€關(guān)于Async簡單的例子,然后再四種啟動線程的方法的對比中讓大家意識到為什么現(xiàn)在的大佬都偏愛Async await.
在這之前,我希望大家首先能知道下面這個事實(shí):

// < : 后者性能高于前者
Thread < ThreadPoll < Task < Async await
注:上述情況只在頻繁使用線程的情況下適用

Async await

方法使用Async修飾符修飾.
返回類型僅有三種: void,Task,Task<T>
方法內(nèi)部使用await關(guān)鍵字標(biāo)明開始執(zhí)行異步代碼
await標(biāo)志前的代碼是同步執(zhí)行,await標(biāo)志的方法是異步執(zhí)行,await標(biāo)志的方法后面的代碼相當(dāng)于"回調(diào)函數(shù)",在await標(biāo)志的異步方法后面執(zhí)行.
所以使用Async await異步編程之后代碼的執(zhí)行順序會變成下面這樣:


Async await編程代碼執(zhí)行順序.png

如果沒看懂上圖,也沒關(guān)系,我們再來看一個小例子:
下面?zhèn)€例子中,我用英文的輸出代表主線程的輸出,中文的輸出代表子線程的輸出

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Let`s Do This!");
            Console.WriteLine("I am going to call my son.");
            AsyncTask();//調(diào)用Async修飾的方法
            Console.WriteLine("My son is busy now,and I will go on.");
            Console.WriteLine("I`m done!");
            Console.ReadLine();
        }

       //Async修飾的方法
        public async Task AsyncTask()
        {
            Console.WriteLine($"我是方法AsyncTask");
            var result= await WasteTime();
            Console.WriteLine(result);
            Console.WriteLine("我已經(jīng)干完了我應(yīng)該干的事情!");
        }

        private async Task<string> WasteTime()
        {
            return await Task.Run(() =>
            {
                Thread.Sleep(1);//避免Console.WriteLine執(zhí)行太快使整個程序執(zhí)行起來像是同步執(zhí)行的
                Console.WriteLine("我開始異步執(zhí)行了!");
                Console.WriteLine("可是我啥都不想干,還是等個五秒鐘就跟主線程說我做好了吧");
                Thread.Sleep(5000);
                return "我異步執(zhí)行完了";
            });
        }
    }

運(yùn)行效果如下:


運(yùn)行效果.png

為什么Thread < ThreadPoll

Thread默認(rèn)創(chuàng)建的是前臺線程,每次初始化一個Thread的示例,就會創(chuàng)建一個新的線程!
ThreadPoll默認(rèn)創(chuàng)建的是后臺線程,每次啟用線程會從線程池尋找空閑的線程,如果找到了,就會調(diào)用這個空閑的線程,而不是直接創(chuàng)建一個新的的線程.
而每次創(chuàng)建一個線程,起碼約消耗1M的內(nèi)存.
因此在需要開啟大量線程的情況下,相比于Thread,ThreadPoll具有減少開啟新線程消耗的資源,以及統(tǒng)一管理線程的優(yōu)勢!

為什么ThreadPoll < Task

ThreadPool使用的是線程池全局隊列寨闹,全局隊列中的線程依舊會存在競爭共享資源的情況胶坠,從而影響性能。
Task基于ThreadPool實(shí)現(xiàn),相當(dāng)于ThreadPoll的優(yōu)化版.它不再使用線程池的全局隊列繁堡,而是使用的本地隊列,使線程之間的資源競爭減少沈善。同時Task提供了豐富的API來管理線程、控制椭蹄。但是相對前面的兩種耗內(nèi)存闻牡,Task依賴于CPU對于多核的CPU性能遠(yuǎn)超前兩者,單核的CPU三者的性能沒什么差別绳矩。

為什么Task < Async await

1.舉個例子:
現(xiàn)在需要實(shí)現(xiàn)一個,異步寫數(shù)據(jù)庫,寫成功之后需要在頁面上彈出一個小窗提示.
如果你用task.result來實(shí)現(xiàn)的話,那么在獲取到結(jié)果之前,task會使你的項(xiàng)目進(jìn)去一個阻塞狀態(tài).也就是說在小窗彈出來之前,你的程序會一直卡主!從而形成異步編程中的同步阻塞
而Async await則不會發(fā)生這種情況.你需要做的僅僅只是在await修飾的方法后面調(diào)一個彈出小窗的方法而已.也就是傳說中的異步阻塞

2.Async await風(fēng)格的編程會使代碼看起來更像是同步代碼,也就更像清新移動更通俗.

結(jié)語

其實(shí)在你理解了異步編程的基礎(chǔ)上,Async await并沒有什么復(fù)雜的.明白了例子中帶返回值的寫法,那別的兩種返回類型應(yīng)該也是信手拈來.從表面上看來,它的編碼風(fēng)格跟同步方法非常相似,以至于新手看到會有一種"我*,這不是同步方法嗎"的感覺,從而給心理上造成了一定負(fù)擔(dān),使自己覺得Async很難,所以懶得去研究了.

最后,如果本篇文章給您帶來了幫助,就點(diǎn)個贊再走唄~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末罩润,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子翼馆,更是在濱河造成了極大的恐慌哨啃,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件写妥,死亡現(xiàn)場離奇詭異拳球,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)珍特,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門祝峻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人扎筒,你說我怎么就攤上這事莱找。” “怎么了嗜桌?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵奥溺,是天一觀的道長。 經(jīng)常有香客問我骨宠,道長浮定,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任层亿,我火速辦了婚禮桦卒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘匿又。我一直安慰自己方灾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布碌更。 她就那樣靜靜地躺著裕偿,像睡著了一般洞慎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嘿棘,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天拢蛋,我揣著相機(jī)與錄音,去河邊找鬼蔫巩。 笑死谆棱,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的圆仔。 我是一名探鬼主播垃瞧,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼坪郭!你這毒婦竟也來了个从?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤歪沃,失蹤者是張志新(化名)和其女友劉穎嗦锐,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沪曙,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奕污,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了液走。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碳默。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖缘眶,靈堂內(nèi)的尸體忽然破棺而出嘱根,到底是詐尸還是另有隱情,我是刑警寧澤巷懈,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布该抒,位于F島的核電站,受9級特大地震影響顶燕,放射性物質(zhì)發(fā)生泄漏凑保。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一割岛、第九天 我趴在偏房一處隱蔽的房頂上張望愉适。 院中可真熱鬧,春花似錦癣漆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽癌蓖。三九已至,卻和暖如春婚肆,著一層夾襖步出監(jiān)牢的瞬間租副,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工较性, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留用僧,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓赞咙,卻偏偏與公主長得像责循,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子攀操,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容