下一代C#裡的async和await

來源:互聯網
上載者:User

C#發展至今,已經從最初的1.0到了4.0版本,不如來回顧一下各個版本都帶來了什麼:

  1. 1.0版本 - 基本C#文法。
  2. 2.0版本 - 泛型的支援,CLR進行了升級,從根本上支援了運行時泛型。
  3. 3.0版本 - LINQ,添加了from / join等類SQL關鍵字,添加了擴充函數,添加了編譯期動態類型var關鍵字。
  4. 4.0版本 - dynamic關鍵字,CLR進行升級,加入DLR,開始對動態進行友好的支援。同時加入動態參數、參數預設值、泛型協變等特性。

可以看到,C#從誕生至今,經曆2次CLR的升級,以及1次文法層面的擴充,其作為一個語言已經非常便利、強大。但是隨著時代的發展,C#依舊在不斷前進,而下一代C# vNext又即將誕生。每一代的C#都會在小的文法調整之外,帶來一個震撼性的特性。從2.0的泛型、3.0的查詢到4.0的動態,每一個版本的C#都有著一個主導的思想,而其他細節的改進和調整則是圍繞著這個最基本的思想給予支援。

在這樣一路明確的有且只有一個主導思想的升級路線上,下一代的C# vNext的核心思想又是什麼呢?縱觀當下的軟體工程界,最熱門的話題莫過於並行計算,為此C#早在4.0版本中就已經引入了Parallel Linq擴充,簡化並行的開發。但是這遠遠不夠,即便Parallel Linq已經提供了極大的便利,但其執行-回調模型依舊打破了編碼人員以往對代碼就是一行一行順序執行的習慣思維。因此,C# vNext的主導思想是在這之上再給予更多的進化,即C# vNext將著眼於:

非同步

C# vNext為了將非同步變得更為簡單,引入了2個關鍵字,asyncawait,下面簡單介紹下這2個關鍵字給我們的編程帶來怎麼樣的改變。

以一個標準的邏輯為例:下載一個遠程URI,並將內容輸出在介面上,假設我們已經有了顯示內容的方法:

void Display(string text) {    // 不管是怎麼實現的}

如果用標準的同步式寫法,這代碼相當之容易:

void ShowUriContent(string uri) {    using (WebClient client = new WebClient()) {        string text = client.DownloadString(uri);        Display(text);    }}

當然這不是我們討論的重點,同步方式會造成線程的阻塞,必須選擇WebClient下載完成才可以繼續運行,如果這個過程在UI線程上執行,則會造成UI無響應的情況。同時網路是非常不可預測的外部條件,很可能因為網路狀況不好導致程式長時間沒有響應,顯然不是我們希望得到的結果。

所以我們又有了非同步方案,.NET中最早的異常編程模式是Begin/End模式,不過WebClient作為WebRequest的高層封裝,已經把這個模式給封裝了:

void DownloadUri(string uri) {    using (WebClient client = new WebClient()) {        client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(ShowContent);        client.DownloadStringAsync(uri);    }}void ShowContent(object sender, DownloadStringCompletedEventArgs e) {    Display(e.Result);}

看看,好好的事情一變成非同步,就變得麻煩無比。一個很明確邏輯的方法活生生拆成2個來處理,雖然可以用Lambda或者delegate來使代碼上進行簡化,但依舊無可避免一段邏輯被拆成兩段的痛苦。當更多的非同步作業交叉在一起的時候,無論是代碼的組織還是邏輯的梳理都會變得更加麻煩。

正因為如此,C# vNext引入了關鍵了,從文法上對此進行了改進,當使用asyncawait時,我們的代碼會變成這樣:

void async ShowUriContent(string uri) {    using (WebClient client = new WebClient()) {        string text = await client.DownloadStringTaskAsync(uri);        Display(text);    }}

悄悄地告訴你,我寫上面這段代碼的時候,是直接把同步方案的代碼複製過來再稍微發了幾個字元的……由此可見,在語言層級給予支援後,代碼的編寫將會是如何地順暢和簡便。這段代碼看上去就是一段典型的同步邏輯,建立-下載-顯示按部就班,唯一不同地就是在方法聲明中加入了async關鍵字,在DownloadStringTaskAsync方法的調用時加入了await關鍵字。就這麼神奇地,運行時變成了非同步。ShowUriContent方法會在調用DownloadStringTaskAsync後退出,而下載過程會非同步進行,當下載完成後,再進入Display方法的執行,期間不會阻塞線程,不會造成UI無響應的情況。

雖然高手們總是說不要關心語言,不要在意語言,真正重要的是思想。但是看著這樣的代碼,真的還能認為語言的優秀與否對生產效率沒有影響嗎?

至於如何?這個效果,本篇並不想做太多的說明,因為本文的目的僅僅是向大家介紹一下下一代C#的一個特性。實現機制方面,相信大家都想得到,編譯器會將方法體在await關鍵字前後打斷,編譯為Begin/End模式的非同步模型。這並不是什麼難事,但是能想到並付諸於實施卻並不容易。至少JAVA7雖然強化了非同步編程,但卻沒有讓語言達到這樣的程度。請不要不屑於文法糖,正如高手們所說,無論什麼語言都不見得能改變設計的代價,那麼實現過程的效率,就決定了項目本身的生產效率。

說回來,這個思想和老趙的[Jscex](http://blog.zhaojie.me/tag/Jscex/ 老趙點滴 - 追求編程之美)非常類似,都是試圖通過一步編譯,將非同步編程模型統一為同步模型,簡化開發複雜度,提升生產效率。時至如今,還想說中國的程式員搞不出創造性的東西嗎?

PS1:怎麼去體驗下C# vNext。

  1. 裝備好Visual Studio 2010 + SP1,無論什麼版本。
  2. 把Visual Studio Async CTP下載下來,並安裝。
  3. 建個項目,現在你已經可以使用asyncawait關鍵字了,而諸如WebClient下的DownloadStringTaskAsync方法,則是在%MyDocument%\Microsoft Visual Studio Async CTP\Samples\AsyncCtpLibrary.dll下定義的擴充方法。

關於具體的實踐和原理,可以看一看[C# 5.0 vNext - New Asynchronous Pattern](http://www.codeproject.com/KB/cs/async.aspx CodeProject)一文。

PS:最後說說為什麼我要寫這一篇。原本我是不想寫關於.NET的內容的,畢竟已經有不短的時間遊走在.NET社區的邊緣,沒有深入地研究,並不適合來發表一些自己的論點。但是看到近段時間部落格園首頁上依舊遍曆著諸如“C#最新特性”這樣的文章時,真的覺得很不舒服。C# 4.0已經出來多久了,C# 5.0都離我們只有多少距離了,我相信關於Async CTP的內容有不少喜歡逛國外部落格的園友是接觸過的,但是卻沒有一個人願意將這些最前沿的訊息分享過來……

當然我也並不認為這個社區的每一員都有義務將自己所知道的內容分享出來,但是現在國內的.NET社區確實存在著這樣的現狀:大家分享的多數是已經被嚼得稀巴爛的骨頭,什麼“C#的可變參數”,什麼“自己寫一個AJAX實現”,這些或許對你個人的學習有著曆史性的意義,但是這樣已經存在、流傳已久,幾乎家喻戶曉的概念,在部落格園首頁這樣的位置傳播,真的有其意義所在嗎?而這些最前沿的變化、那些更加深入的探究,或者是沒人接觸,或者就是接觸了但不願意分享。這並不是我所希望的社區狀態,如今的互連網,無論是SNS還是微博,大家都在注重著訊息的傳播這一環節,為什麼在.NET社區裡,卻是死氣沉沉的狀態,把舊菜炒了又炒,滿眼都見不到一絲亮點?

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.