C#并发编程之异步编程(一)
寫在前面
C#5.0中,對異步編程進行了一次革命性的重構,引入了async和await這兩個關鍵字,使得開發人員在不需要深刻了解異步編程的底層原理,就可以寫出十分優美而又代碼量極少的代碼。如果使用得當,你可以寫出具有并行化并且性能較高的程序,但是同時也增加了對異步編程理解的復雜度,畢竟在C#5.0里,你已經看不到異步編程具體是如何實現的了,需要花費額外的經歷去研究探索。
使用異步編程,使得我們釋放了啟動它的線程,也使得資源的占有量下降。更重要的是,有些特殊線程,比如UI線程,在運行的時候只能啟動一個,如果沒有快速響應,頁面將會出現卡頓現象。本文只會基于.NET FX4.5及以后的版本進行講解,之前的版本如果要實現異步編程,需要從nuget上面下載Microsoft.Bcl.Async,不過我還是建議你,如果想要在系統中大量使用編寫異步代碼,還是要是使用.NET FX4.5或更高的版本
異步編程主要分為基于事件的異步模式(EAP)和基于任務的編程模式(TAP)。EAP在調用方法之前立即注冊事件,它具有void返回類型,但這種模式比較混亂,它將原本的一個方法分拆成兩個方法。本系列主要關注TAP編程而不涉及EAP編程。
異步編程是什么
異步關鍵字
作為C#5.0中新增的重量級功能,異步功能是指程序在進行長時間操作完成后,需要繼續執行的操作的一種方法,在編程過程中,會感覺這些異步代碼和同步或者阻塞代碼類似,但是實際上,編譯器會將標識為異步的方法進行進一步的轉換,是的代碼可以實現真正的異步編程。它主要以兩個關鍵字的形式功能大家使用:
async
await
以下以一個通過EF Core查詢用戶信息的代碼片段,這個例子沒有什么特殊的地方
public Users GetUserInfo(string userId)
{
using (UserDbContext db = new UserDbContext())
{
var user = db.Users.FirstOrDefault(p => p.UserId = userId);
return user;
}
}
接下來我們看看異步的實現代碼
public async Task<Users> GetUserInfoAsync(string userId)
{
using (UserDbContext db = new UserDbContext())
{
var user = await db.Users.FirstOrDefaultAsync(p => p.UserId = userId);
return user;
}
}
以上兩段代碼看起來非常的類似,但是仔細看卻有明顯的不同。異步方法上多了一個async的標識,同時返回值User,被標識成了Task<Users>,同時在進行數據庫查詢的時候,使用到了await。這里提前說一下await關鍵字,當編譯器看到await關鍵字的時候,會截斷方法,便于線程調度。簡單點說,就是當調用線程運行到FirstOrDefaultAsync時,查詢開始,但不是在當前線程,在新的線程里面,我們查詢完數據庫后,根據需要做進一步處理,比如,如果原線程UI線程,它將返回以繼續處理用戶的其他操作(這里非常類似回調方式),否則的話,這個線程就直接被釋放了。這段可能比較抽象,會在之后的系列里進一步講解。
為了更好的進行異步編程,我們需要在方法簽名后面追加Async,這是一種異步編程的規約,也希望大家遵守。
雖然異步編程對系統以及用戶的體驗非常的有幫助,但如果對異步編程不甚了解,可能會發生一些令人感到詭異的問題,而且這些問題可能通過debug方式也很難得到解決。
異步執行流程
1、想象一下,在現實世界中,一個顧客到電腦專賣店買東西,就是那種拿了就走的場景。如果店鋪只有一個人,在與顧客1沒有結算完成之前,對顧客2的請求,只能暫時放置一下。相信大家在現實世界中,肯定會遇到類似的情況,心情可能也很不爽,如果不是很迫切,可能是再看看,換一家店,如果比較著急,就會一直催,然后也不一定會有回應。
如下圖所示
2、有一天,老板請了幾個伙計幫忙搬電腦,在顧客1沒有結算完成之前,老板就可以接住顧客2的需求,并通過信息系統或者大吼一嗓子的方式,讓電腦準備顧客2的電腦。同時,電腦把顧客1的電腦搬到前臺,由老板去跟顧客結算,整個的流程就顯得體驗度很高,顧客也不會被忽略,賣出去的東西也多了很多,不過等待還是要等的。
如下圖所示
?
寫在后面
本文主要介紹了異步編程的基礎,通過以上介紹,我們知道要創建一個異步函數,首先需要用async去修飾一個方法,同時返回值類型必須是Task或者Task<T>,當然在使用UI控制器時間處理的時候是可以使用async void的。在方法內部,需要使用await關鍵字。異步函數會被編譯器編譯成復雜的程序結構,可以視其為一種狀態機。不過需要提醒的是,如果不需要編寫異步函數,那就用同步。
雖然異步編程已經變得非常簡單,但是大家同樣需要了解異步編程背后的理念以及原理,這有助于我們編寫高性能高擴展的應用程序。
總結
以上是生活随笔為你收集整理的C#并发编程之异步编程(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HAProxy 2.0发布,长期支持版本
- 下一篇: c# char unsigned_dll