首先,在mvc中若是要用純異步請不要使用async和await,能夠直接使用Task.Run。web
其次,在mvc中使用async和await可讓系統開新線程處理Task的代碼,同時沒必要等Task執行結束,就能夠同時運行Task以後的代碼,加快效率。數據庫
要注意的是:若是使用async和await,系統雖然能夠同時處理多個事務,但客戶端(瀏覽器)不會有響應,依然要等到全部代碼所有執行完畢(包括異步的代碼)才能正常響應。編程
/* * 演示如何利用 .net 4.5 的新特性實現異步操做 * * 什麼場景下須要異步操做? * 在由於磁盤io或網絡io而致使的任務執行時間長的時候應該使用異步操做,若是任務執行時間長是由於cpu的消耗則應使用同步操做(此時異步操做不會改善任何問題) * 原理是什麼? * 在 Web 服務器上,.NET Framework 維護一個用於服務 ASP.NET 請求的線程池(如下把 .NET Framework 維護的用於服務 ASP.NET 請求的線程池稱做爲「特定線程池」) * 同步操做時,若是特定線程池利用滿了,則不會再提供服務 * 異步操做時: * 一、一個請求過來,特定線程池出一個線程處理此請求 * 二、啓動一個非特定線程池中的另外一個線程處理異步操做,此時處理此請求的線程就會空出來,不會被阻塞,它能夠繼續處理其它請求 * 三、異步操做執行完畢後,從特定線程池中隨便找一個空閒線程返回請求結果 */
實際工做中,async和await咱們能夠用於相似用戶上傳頭像、上傳照片這種的耗時較長的功能中,咱們能夠在邊上傳照片時邊處理數據庫的其餘事務。瀏覽器
而純異步則多用於時間較長,而無需結果實時看反饋給用戶的操做,例如:管理在後臺備份數據庫、清理垃圾文件等。服務器
若是async和await的異步方法是有返回值的,並且主方法中又要使用這個返回值,那麼將不會實現多個異步方法同時執行,要等異步結果後才繼續執行,至關於異步並未起到多程序同時處理事務的目的。這僅是對於Web或控制檯程序而言的,若是對於Winform則有大大的不一樣,由於Winform若是使用異步時界面是能夠響應的。網絡
Web中異步更多的是用來實現大量IO操做,或大量調用WCF、WebService時使用。多線程
因此,在Mvc這種Web界面中使用async和await異步的實際意義就不是很大了,由於界面老是沒有響應的,並且也沒法實現多線程同時工做。mvc
有須要請看這篇:http://www.dozer.cc/2012/03/async-and-await-in-web-application/app
async的做用是異步執行,await的做用是等待執行結果(會卡住異步方法中await如下的代碼,但不會卡死主線程)。
異步
async通常最終都須要一個async void方法來進行最高層的調用。好比:private async void Sync_Button_Click(object sender, RoutedEventArgs e),C#中也提供了大量的可設置async的系統方法和事件。
class Program { private static async void Test() { Task<int> t = new Task<int>(() => { Thread.Sleep(3000); return 1; }); t.Start(); int tr = await t; Console.WriteLine(tr); } static void Main(string[] args) { Test(); Console.WriteLine("Main"); Console.ReadKey(); } }
Test函數就用最簡單的方法使用了這兩個關鍵字,執行這段代碼,首先輸出「Main」,而後3秒鐘後會輸出「1」。
也可使用:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication11 { class Program { static void Main(string[] args) { Test(); Console.WriteLine("Main"); Console.ReadKey(); } private static async void Test() { var t = Task<int>.Run(() => { Thread.Sleep(3000); return 1; }); Console.WriteLine(await t); } } }
使用async異步編程時,請注意以下事項:
private async void Sync_Button_Click(object sender, RoutedEventArgs e) { 2: OutputTextBlock.Text += "開始" + Environment.NewLine; 3: // 這裡會等 getFileContentAsync() 執行完畢後, 再執行貼上結束字串那一行 4: // 因為 Compiler 會再 await 這行下斷點 5: OutputTextBlock.Text += await getFileContentAsync(); 6: OutputTextBlock.Text += "結束" + Environment.NewLine; 7: } 8: 9: private async Task<string> getFileContentAsync() { 10: StorageFolder folder = KnownFolders.DocumentsLibrary; 11: StorageFile file = await folder.GetFileAsync(TESTED_FILE_NAME); 12: var result = await FileIO.ReadTextAsync(file) + Environment.NewLine; 13: return result; 14: }