在編程的過程當中,咱們會遇到不少須要異步操做的場景。好比要下載一個文件,若是使用同步的方式進行下載,那麼UI操做就會被卡住,這時最好可以使用異步的方式進行下載。在C#中,很早就開始支持異步的操做了,只不過早期的方法寫起來有些麻煩。到了C# 5.0的時候,直接添加了兩個關鍵字:async 和 await,這下對異步操做的支持可謂是達到了完美。下面咱們就通用一個簡單的 demo 看一下它們的基本用法。python
咱們先看看用同步的方式下載一個文件:程序員
private void btnOldDownload_Click(object sender, EventArgs e) { using(WebClient wc = new WebClient()) { // 咱們嘗試去下載 python 的安裝包。 wc.DownloadFile("https://www.python.org/ftp/python/3.5.2/python-3.5.2-amd64.exe", "python.exe"); } lbMessage.Text = "下載完成。"; }
在執行 DownloadFile 方法的過程當中,UI線程被卡死,整個的下載過程當中應用程序都處於沒響應的狀態。這固然是不能接受的,因此咱們應該使用下面的異步方式進行文件的下載。編程
咱們先看一下使用早期的異步代碼去下載文件:異步
private void OldAsyncDownload_Click(object sender, EventArgs e) { using (WebClient wc = new WebClient()) { // 咱們嘗試去下載 python 的安裝包。 // 下載完成時會有事件通知。 wc.DownloadFileCompleted += Wc_DownloadFileCompleted; wc.DownloadFileAsync(new Uri("https://www.python.org/ftp/python/3.5.2/python-3.5.2-amd64.exe"), "python.exe"); } } private void Wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { lbMessage.Text = "下載完成。"; }
好吧,事情變得稍微有點複雜了。一個簡單的下載邏輯竟然被分隔到了兩個方法中!在第一個方法中掛載 DownloadFileCompleted 事件,而後啓動下載。下載完成後經過 DownloadFileCompleted 事件處理函數進行通知。若是您可以習慣於這樣的寫法,其實C# 早期提供的異步編程接口已經足夠用了,由於這也正是異步操做真正的實現方式。async
可是,做爲程序員,咱們是不會知足的,永遠不會…異步編程
在C# 5.0 中引入了 async 和 await 關鍵字,它們使得異步操做的實現更加簡單、容易!函數
private async void btnMyAsync_Click(object sender, EventArgs e) { using (WebClient wc = new WebClient()) { // 咱們嘗試去下載 python 的安裝包。 Task task = wc.DownloadFileTaskAsync("https://www.python.org/ftp/python/3.5.2/python-3.5.2-amd64.exe", "python.exe"); // 能夠在這裏執行代碼。 await task; } lbMessage.Text = "下載完成。"; }
注意代碼中 async 和 await 關鍵字的位置,這樣代碼就是以異步方式去執行下載邏輯,整個過程當中UI 操做不會被阻塞掉。是否是很神奇呢?spa
這段代碼最大的魔力在於它和同步下載文件的代碼幾乎相同!每一個 人都喜歡寫順序執行的代碼,這樣的代碼邏輯也最清晰。async 和 await 的最大優點就是把人腦感受簡單的代碼轉換爲真正的異步操做邏輯。線程