日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#异步编程看这篇就够了

發布時間:2023/12/4 C# 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#异步编程看这篇就够了 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

隨著.NET Core的流行,相信你現在的代碼中或多或少的會用到async以及await吧!畢竟已成標配。那么我們為什么要用async以及await呢?其實這是微軟團隊為我們提供的一個語法糖,讓我們不用996就可以輕松的編寫異步代碼,并無太過神奇的地方。那么,問題來了,什么是異步?異步到底又是怎樣的一個過程呢?

從一個故事說起

在開始講異步前我們先從一個生活中的小故事說起吧。話說2019年12月15日周日這一天有位程序猿小祝在這天居然沒有加班,選擇在家休息了,然后他習慣性的用Microsoft To Do羅列了一下這天要做的事情,如下圖所示:

這一天這個程序猿小祝計劃早上九點起床洗澡,然后吃早餐,洗衣服,分享一篇關于C#異步相關的文章,晚上在家加下班~~沒錯,這個苦逼休息的時候也得工作,不然下周的任務有可能完不成要挨批了。

這個時候這個程序猿小祝可以選擇,1.起床洗澡,2.吃早餐,3.洗衣服,4.寫文章,5.打會球然后“遠程寫代碼”。這個過程有嚴格的執行順序,這個過程可以視為一個同步的過程。如下圖所示:

當然,這個程序猿小祝卻采用了另一種方式來進行:起床后先把衣服換下來用洗衣機洗了,然后開始洗澡,然后吃飯,寫了一會文章,然后等衣服洗好后再把衣服給晾好繼續回來寫文章,最后在晚上的時候遠程寫代碼。在這個過程中這個程序猿在洗衣服的同時就去洗澡,吃飯寫了會文章了,這個過程就是一個異步的過程。

可能這個故事比喻的不恰當,不過大伙將就著看下吧,總結一下同步跟異步吧:

  • 同步方法:可以認為程序是按照你寫這些代碼時所采用的順序執行相關的指令的。

  • 異步方法:可以在尚未完成所有指令的時候提前返回(如上面的洗衣服過程沒執行完就返回去洗澡了),等到該方法等候的那項任務執行完畢后,在令這個方法從早前還沒執行完的那個地方繼續往下運行(如:衣服洗好晾好后,繼續寫文章了)。

  • 下面我們結合偽代碼來進行更加詳細的講解吧。

    偽代碼實例講解

    這一節我們就用偽代碼來分別實現下同步過程及異步過程吧。

    同步過程

    下面我們用偽代碼來實現上述故事中的過程吧。

    static?void?Main(string[]?args){Console.WriteLine("Main異步演示開始~~~~~");Stopwatch?stopwatch?=?Stopwatch.StartNew();Bash();//洗澡BreakFast();//吃早餐WashClothes();//洗衣服WriteArticle();//寫文章WritingCode();//寫代碼Console.WriteLine("Main異步演示結束~~~~~共用時{0}秒!",?stopwatch.ElapsedMilliseconds/1000);Console.ReadKey();}private?static?void?Bash(){Console.WriteLine("洗澡開始~~~~~");Thread.Sleep(1*1000);//模擬過程Console.WriteLine("洗澡結束~~~~~");}private?static?void?BreakFast(){Console.WriteLine("吃早餐開始~~~~~");Thread.Sleep(1?*?1000);//模擬過程Console.WriteLine("吃早餐結束~~~~~");}private?static?void?WashClothes(){Console.WriteLine("洗衣服開始~~~~~");Thread.Sleep(6?*?1000);//模擬過程Console.WriteLine("洗衣服結束~~~~~");}private?static?void?WriteArticle(){Console.WriteLine("寫文章開始~~~~~");Thread.Sleep(20?*?1000);//模擬過程Console.WriteLine("寫文章結束~~~~~");}private?static?void?WritingCode(){Console.WriteLine("寫代碼開始~~~~~");Thread.Sleep(12?*?1000);//模擬過程Console.WriteLine("寫代碼結束~~~~~");}

    上面的代碼沒什么難的,寫完代碼后我們直接dotnet run一下代碼,如下圖所示:

    我們可以看到這個代碼的執行過程是嚴格按照我們編碼的順序執行的,即同步運行的代碼。這里用時共40秒!

    異步過程

    我們只需要稍微改造下使得代碼異步執行再來看下效果吧!偽代碼如下:

    static?async?Task?Main(string[]?args){Console.WriteLine("Main異步演示開始~~~~~");Stopwatch?stopwatch?=?Stopwatch.StartNew();List<Task>?tasks?=?new?List<Task>{Bash(),//洗澡};tasks.Add(BreakFast());//吃早餐tasks.Add(WashClothes());//洗衣服tasks.Add(WriteArticle());//寫文章tasks.Add(WritingCode());//寫代碼await?Task.WhenAll(tasks);Console.WriteLine("Main異步演示結束~~~~~共用時{0}秒!",?stopwatch.ElapsedMilliseconds/1000);Console.ReadKey();}private?static?async?Task?Bash(){Console.WriteLine("洗澡開始~~~~~");await?Task.Delay(1*1000);//模擬過程Console.WriteLine("洗澡結束~~~~~");}private?static?async?Task?BreakFast(){Console.WriteLine("吃早餐開始~~~~~");await?Task.Delay(1?*?1000);//模擬過程Console.WriteLine("吃早餐結束~~~~~");}private?static?async?Task?WashClothes(){Console.WriteLine("洗衣服開始~~~~~");await?Task.Delay(6?*?1000);//模擬過程Console.WriteLine("洗衣服結束~~~~~");}private?static?async?Task?WriteArticle(){Console.WriteLine("寫文章開始~~~~~");await?Task.Delay(20?*?1000);//模擬過程Console.WriteLine("寫文章結束~~~~~");}private?static?async?Task?WritingCode(){Console.WriteLine("寫代碼開始~~~~~");await?Task.Delay(12?*?1000);//模擬過程Console.WriteLine("寫代碼結束~~~~~");}

    然后我們再直接dotnet run一下代碼,如下圖所示:

    我們可以看到這個代碼的執行過程中遇到await后就會返回執行了,待await的代碼執行完畢后才繼續執行接下來的代碼的!為了避免有的讀者看不懂,我簡單分析其中一個方法的執行過程吧。具體的還需要你自己把異步代碼拷貝下來,多打幾個斷點,然后把等待時間*100(時間長點方便我們查看斷點的進入順序,否則時間短,還沒來得及進斷點可能代碼已經執行完了)看看斷點的進入步驟吧!

    我也只列了一部分,具體的你們自行打斷點看下吧。

    異步原理解析

    通過上面的偽代碼分析相信你已經對異步有所了解了。接下來我們就來看看系統到底是怎么實現出這樣的效果的。下面只是簡單地進行下表述,如果不正確的歡迎大家指正。

    編譯器在處理異步方法的時候,會構建一種機制,該機制可以啟動await 語句所要等候的那項異步任務,并使得程序在該工作完成之后,能夠用某個線程繼續執行await語句后面的那些代碼。這個await語句正是關鍵所在。編譯器會構建相應的數據結構,并把await之后的指令表示成delegate,使得程序在處理完那項異步任務之后,能夠繼續執行下面的那些指令。編譯器會把當前方法中的每一個局部變量的值都保存在這個數據結構中,并根據await語句所要等候的任務來配置相應的邏輯,讓程序能夠在該任務完成之后指派某個線程,從await語句的下一條指令開始繼續執行。實際上,這相當于編譯器生成了一個delegate,用以表示await語句之后的那些代碼,并寫入了相應的狀態信息,用以確保await語句所等候的那項任務執行完畢以后這個delegate能夠正確的得到調用。

    這使得該方法看上去好像是從早前暫停的地方繼續往下執行了,也就是說,系統會把狀態恢復到早前暫停的樣式,并且直接把程序中的某個線程放到適當的語句上,令其能夠繼續向下運行。

    這個過程實際上是由SynchronizationContext類來實現的,該類用來保證異步方法能夠在它所等候的任務執行完畢時,從早前停下來的地方繼續往下運行,并確保該方法此時所處的環境與上下文能夠與當初的情況一樣。

    總結

    通過上面的講述我們可以知道通過async與await關鍵字寫出來的異步方法并沒有太過神奇的地方。只不過編譯器會針對這種方法生成許多代碼,使得調用這個方法的主調方無需等待該方法完工,就可以繼續往下執行,并確保該方法所等候的那項任務在執行過程中發生的錯誤能夠適當的得到回報。這樣的好處是,如果異步方法執行到await語句時它所要等候的那項任務還沒有完成,那么該方法的執行進度就會暫停在那里,直到那項任務完成之后,才會繼續往下執行。

    希望這篇文章對你有所幫助,當然光了解異步沒用,還要能夠高效的編寫異步代碼才行哦,接下來我會抽時間講講進行異步開發的一些建議。當然我以前也寫過相關的文章,你可以提前看下。同時歡迎大家加入.net core兩千人交流群637326624`交流。當然我不會告訴你,關注公眾號會第一時間收到文章推送。

    很久沒寫文章了,生疏了很多,大家將就著看吧!

    參考

    《More Effective C#》機械工業出版社

    依樂祝自己的理解

    好看你就點點我

    總結

    以上是生活随笔為你收集整理的C#异步编程看这篇就够了的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。