async await的教程:http://www.javashuo.com/article/p-fgxlmiin-z.htmlhtml
異步方法:web
private async Task<string> TestAsync() { Console.WriteLine("異步方法開始"); var task = Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("在新線程中"); return "新線程結束"; }); var result = await task; Console.WriteLine("異步方法結束"); return result; }
調用時不使用await微信
public IActionResult Index() { Console.WriteLine("主線程開始"); Console.WriteLine("輸出結果:" + TestAsync()); Console.WriteLine("主線程結束"); }
結果:異步
一、主線程+異步方法內await以前的代碼按順序執行async
二、await開始(開新線程)微信支付
三、跳出異步方法(不等待),繼續執行主線程後續代碼,此時Console.WriteLine("輸出結果:" + TestAsync());拿不到TestAsync()的值編碼
四、異步方法await執行結束後,異步方法await後的代碼繼續執行spa
調用時使用await線程
public async Task<IActionResult> Index() { Console.WriteLine("主線程開始"); Console.WriteLine("輸出結果:" + await TestAsync()); Console.WriteLine("主線程結束"); }
結果:3d
所有按順序執行,能夠正確拿到返回值
async await在winform中的優勢是,不卡主線程,而且執行順序不混亂,但在MVC做用有限,由於web主不結束界面老是無響應的
在MVC中,若是有一種需求,如微信支付後臺的交易記錄打包下載,在這種需求時,打包下載功能耗時較長,此時咱們但願網頁不等待打包完成,只起到「打包中,稍後查看」的提示做用,那麼就能夠:
private Task BagAsync() { var task = Task.Run(() => { Console.WriteLine("打包開始"); Thread.Sleep(2000); Console.WriteLine("打包結束"); }); return task; } public IActionResult Index() { Console.WriteLine("準備打包"); BagAsync(); Console.WriteLine("後臺打包中,請稍後查看。"); }
結果:
若是之後,咱們又想等打包結束之後,再顯示結果,咱們能夠在主方法中加入await等待就行,這樣一個打包方法,能夠根據調用者的意願,隨時等待或不等待:
private Task BagAsync() { var task = Task.Run(() => { Console.WriteLine("打包開始"); Thread.Sleep(2000); Console.WriteLine("打包結束"); }); return task; } public async Task<IActionResult> Index() { Console.WriteLine("準備打包"); await BagAsync(); Console.WriteLine("打包成功。"); }
結果:
因爲BagAsync()方法沒有標記async,因此他自己沒有await功能,因此在BagAsync方法編寫時,在Task.Run以後的方法,將不會等待,必定注意執行順序!可手動等待。
爲何BagAsync不標記async呢?是由於標記了async,可是咱們的需是不想等待時,那麼vs編譯器,將會有一個提醒,固然,你也可不理它,但老是以爲比較煩。
被調用的異步方法在編寫時,不必定非得要async,也能夠只是一個普通的Task方法,由主調用方法來決定是否須要等待。
若是一個方法沒有使用await,直接調用了一個普通的異步方法(無async標記),那麼不會有警告,也不影響執行。
若是一個方法沒有使用await,直接調用了一個標記了async的異步方法,那麼這個方法自己無需標記async,編譯器會有警告,但不影響執行。
若是一個方法使用await,來調用一個標記了async的異步方法或普通異步方法,那麼這個方法也須要標記成async,不然沒法經過。
若是一個異步方法自己標記了async,代碼裏卻沒有await編譯器會有的提示,但不影響執行。
若是咱們的異步方法沒有返回值,並在異步方法內不須要等待,則能夠不寫成async,不然會在調用時時常會有警告,使人不爽。
若是咱們的異步方法擁有返回值,或在異步方法內須要等待,則能夠寫成async,不然沒法使用await,提高編碼複雜度。
async自己是一個語法糖,請靈活使用