真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C#中怎么實現(xiàn)異步編程

這篇文章給大家介紹C#中怎么實現(xiàn)異步編程,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

十多年的沙洋網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。營銷型網(wǎng)站的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整沙洋建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)從事“沙洋網(wǎng)站設(shè)計”,“沙洋網(wǎng)站推廣”以來,每個客戶項目都認(rèn)真落實執(zhí)行。

異步方法基礎(chǔ)及其運行流程

Async和Await

異步方法使用async修飾,該方法包含一個或多個await表達(dá)式或語句,方法同步運行,直至到達(dá)第一個 Await,此時暫停,直到等待的任務(wù)完成,在任務(wù)完成后,控制權(quán)返回給方法的調(diào)用方。如果方法中并不包含await,則該方法不會像同步方法一樣被掛起。

異步方法通常包含await運算符的一個或多個實例,但缺少await表達(dá)式也不會導(dǎo)致生成編譯器錯誤,之會因為沒有await而發(fā)出警告,但編譯依然通過。

異步方法使用await關(guān)鍵字來確定等待位置,但await表達(dá)式并不阻止正在執(zhí)行到此位置的線程,也就是說異步方法在await表達(dá)式執(zhí)行時只是暫停,并不會導(dǎo)致方法退出,只會導(dǎo)致finally代碼塊不運行。異步方法只有在等待的任務(wù)完成后,才能通過該位置并繼續(xù)執(zhí)行剩下的邏輯,控制權(quán)也在此處返回給異步方法的調(diào)用方。

如果異步方法未使用Await運算符標(biāo)記暫停點,那么異步方法會作為同步方法執(zhí)行,即使有Async修飾符,也不例外。如以下示例

   1:  public async static Task GetUserInfoAsync()
   2:  {
   3:      User user = await db.User.FirstOrDefaultAsync();//此處會掛起
   4:
   5:      Task user = db.User.FirstOrDefaultAsync();//此處不會掛起,注意此處,返回值也變了,接下來會討論一下異步方法的返回值
   6:
   7:      return string.Empty;
   8:  }
 

具M(jìn)SDN描述,aysnc關(guān)鍵字是一個非保留的關(guān)鍵字。在修飾方法或 lambda 表達(dá)式時,它是關(guān)鍵字,await也作為關(guān)鍵字存在。在所有其他上下文中,async和await都會將其解釋為標(biāo)識符。不過開發(fā)人員可以不用太過關(guān)注這段,只需要知道aysnc會將一個方法標(biāo)識成異步方法,而await可以掛起異步方法的執(zhí)行即可。


 

關(guān)鍵點

1、和被async修飾的方法不一樣,如果方法中含有await關(guān)鍵字,方法必須使用async標(biāo)識符,否則編譯不通過。

2、在異步編程過程中,比較推薦的做法是,被標(biāo)記了async關(guān)鍵字的異步方法應(yīng)該包含至少一個await表達(dá)式或語句。

3、異步方法的命名以Async結(jié)尾 

異步返回類型和異常處理

需要說明的是,本文所討論的異步方法指的是基于任務(wù)的異步編程模型,返回值是,Task或Task

1、如果方法需要返回string類型,那么將返回Task。如果方法沒有指定返回類型,那么將返回Task。每個返回的任務(wù)都表示正在進(jìn)行的工作,任務(wù)封裝有關(guān)異步進(jìn)程狀態(tài)的信息,如果未成功,則會引發(fā)異常。異步方法返回 Task 或 Task。返回任務(wù)的屬性攜帶有關(guān)其狀態(tài)和歷史記錄的信息,如任務(wù)是否完成、異步方法是否導(dǎo)致異常或已取消以及最終結(jié)果是什么。可使用await運算符訪問這些屬性。

   1:  public async static Task GetUserInfoAsync()
   2:  {
   3:      User user = await db.User.FirstOrDefautAsync();
   4:
   5:      return user;
   6:  }

2、如果等待的任務(wù)返回異步方法導(dǎo)致異常,則 await 運算符會以同步方式拋出異常。如果等待的返回任務(wù)的異步方法取消,await運算符引發(fā)OperationCanceledException。如果異步方法中沒有使用await阻塞,可以使用try-catch捕捉異常,只是異常發(fā)生的時機可能會滯后。

異步方法的運行流程

了解異步方法的運行機制,就是要了解異步編程中的控制流是如何一步步執(zhí)行的。如果需要詳細(xì)了解控制流,可以異步到MSDN中查看。

下圖及其描述摘自MSDN:

C#中怎么實現(xiàn)異步編程

關(guān)系圖中的數(shù)值對應(yīng)于以下步驟。

  1. 事件處理程序調(diào)用并等待 AccessTheWebAsync 異步方法。

  2. AccessTheWebAsync 創(chuàng)建HttpClient實例并調(diào)用GetStringAsync異步方法,獲取的內(nèi)容字符串方式返回。

  3. GetStringAsync 中發(fā)生了某種情況,該情況掛起了它的進(jìn)程??赡鼙仨毜却渌柚谷蝿?wù)完成。為避免阻止資源,GetStringAsync 會將控制權(quán)出讓給其調(diào)用方 AccessTheWebAsync。 GetStringAsync 返回Task,其中 TResult 為字符串,并且 AccessTheWebAsync 將任務(wù)分配給 getStringTask 變量。該任務(wù)將調(diào)用GetStringAsync正在進(jìn)行的進(jìn)程,在調(diào)用完成時產(chǎn)生返回字符串給urlcontent。

  4. 由于尚未等待 getStringTask,因此,AccessTheWebAsync 可以繼續(xù)執(zhí)行而不依賴于 GetStringAsync 最終結(jié)果的完成。該任務(wù)繼續(xù)調(diào)用同步方法 DoIndependentWork。

  5. DoIndependentWork 作為一個同步方法,在自身工作完成后返回到調(diào)用方。

  6. AccessTheWebAsync 已運行完畢,可以不受 getStringTask 的結(jié)果影響。接下來,AccessTheWebAsync 需要計算并返回已下載的字符串的長度,但該方法只有在獲得字符串的情況下才能計算該值。

    因此,AccessTheWebAsync 使用一個 await 運算符來掛起其任務(wù),并把控制權(quán)交給調(diào)用 AccessTheWebAsync 的事件處理程序。 AccessTheWebAsync 將 Task返回給調(diào)用方。該任務(wù)將計算下載字符串長度。 

  7. GetStringAsync 完成并生成一個字符串結(jié)果。字符串結(jié)果不是通過按你預(yù)期的方式調(diào)用 GetStringAsync 所返回的。(記住,該方法已返回步驟 3 中的一個任務(wù))。相反,字符串結(jié)果存儲在表示 getStringTask 方法完成的任務(wù)中。await 運算符從 getStringTask 中檢索結(jié)果。賦值語句將檢索到的結(jié)果賦給 urlContents。

  8. 當(dāng) AccessTheWebAsync 獲取字符串結(jié)果時,該方法可以計算字符串長度。然后,AccessTheWebAsync 工作也將完成,并且等待事件處理程序的繼續(xù)使用。事件處理程序也將最終獲得字符串的長度信息。

注意:

如果 GetStringAsync(因此 getStringTask)在 AccessTheWebAsync 等待前完成,則控制權(quán)會保留在 AccessTheWebAsync中。如果異步調(diào)用過程 (AccessTheWebAsync) 已完成,并且 AccessTheWebSync 不必等待最終結(jié)果,則掛起然后返回到 getStringTask 將造成資源浪費。

在調(diào)用方內(nèi)部(此示例中的事件處理程序),處理模式將繼續(xù)。在等待結(jié)果前,調(diào)用方可以開展不依賴于 AccessTheWebAsync 結(jié)果的其他工作,否則就需等待片刻。事件處理程序等待 AccessTheWebAsync,而 AccessTheWebAsync 等待 GetStringAsync。

異步編程對性能的影響

 在.NET異步編程中,async和await不會創(chuàng)建其他線程,同時異步方法不會在其自身線程上運行,因此它不需要多線程。只有當(dāng)方法處于活動狀態(tài)時,該方法將在當(dāng)前同步上下文中運行并使用線程上的時間??梢允褂肨ask.Run將占用大量CPU的工作移到后臺線程,但是后臺線程不會幫助正在等待結(jié)果的進(jìn)程變?yōu)榭捎脿顟B(tài)。

對于異步編程而言,基于異步的方法優(yōu)于幾乎每個用例中的現(xiàn)有方法。具體而言,這種方法優(yōu)于BackgroundWorker的I/O綁定操作因為代碼更簡單且無需防止?fàn)幱脳l件。結(jié)合Task.Run使用時,異步編程比BackgroundWorker更適用于CPU綁定的操作,因為異步編程將運行代碼的協(xié)調(diào)細(xì)節(jié)與Task.Run傳輸至線程池的工作區(qū)分開來。

那么異步編程對線程的影響又是什么呢,相比大家應(yīng)該都知道,ASP.NET中有兩類線程,工作線程,和IO線程。

其中工作線程處理普通請求的線程,也是我們用得最多的線程。這個線程是有限的,是根CPU的個數(shù)相關(guān)的。IO線程,比如與文件讀寫,網(wǎng)絡(luò)操作等是可以異步實現(xiàn)并且使性能提升的地方。I/O線程通常情況下是空閑的。所以可以使用IO線程來代替工作線程,一方面充分運用了系統(tǒng)資源,另一方面也節(jié)省了工作線程調(diào)度及切換所帶來的損耗。

由此我們需要明白,在I/O密集型處理時,使用異步可以帶來很大的提升,比如數(shù)據(jù)庫操作以及網(wǎng)絡(luò)操作。

即便異步編程帶來性能的提升,但是運用不慎,也會對系統(tǒng)性能產(chǎn)生反作用,比如直接使用Task.Run或者Task.Factory.StartNew所帶來的異步編程,這些方式會占用工作線程以及工作線程之間的切換。 

異步編程需要注意的地方


 

1、同時async和await侵入性或者傳遞性很強,所有調(diào)用的地方都需要同步使用async和await,這對系統(tǒng)中老代碼的修改產(chǎn)生了很大的影響。

2、異步編程中無法使用lock鎖,因為異步方法不會在自身線程上運行,lock就變成了多余的了。但異步編程場景下可以使用AsyncLock鎖,對相應(yīng)的代碼進(jìn)行鎖定。

3、異步編程里,比較推薦的做法是避免上線文延續(xù),此處不再做更多說明,參考我的前一篇文章《異步編程(一)》

4、異步編程是否真的提升了系統(tǒng)性能,目前來看大多數(shù)場景下是提升了,尤其在I/O操作比較密集的業(yè)務(wù)場景下,比如查詢數(shù)據(jù)庫和網(wǎng)絡(luò)調(diào)用。

關(guān)于C#中怎么實現(xiàn)異步編程就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。


分享題目:C#中怎么實現(xiàn)異步編程
網(wǎng)頁路徑:http://weahome.cn/article/gsheeh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部