2012年6月25日 星期一

Metro Style App與.NET 4.5中的非同步程式設計概念

非同步,是最近這幾年很重要的程式設計與開發概念。

過去,我們在寫程式的時候,總是從上到下一行一行執行,但隨著CPU運算能力越來越強大,且展示層的User Experience要求越來越高,用戶不容許今天我們的程式碼在跑長時間動作(例如開啟一個很大的檔案、或是讀取遠端資料庫或網路上的資料)時,畫面停止回應。

因此,最近這幾年程式設計都轉變成透過非同步的方式來設計,例如底下這樣的Silverlight程式碼:

在DownloadStringAsync的非同步Method呼叫下,返回值並不會立刻取得,而是在相對應的Completed事件當中取得,但這樣導致做一件工作需要拆成兩三段來寫,如果在非同步的呼叫之後,又要再次呼叫非同步方法,就會變成底下這樣:

這導致維護與程式碼閱讀的困難,更讓例外(Exception)處理變得很礙手礙腳。因此,在.NET 4.5和Windows的Metro Style App當中,開始有了新的非同步程式設計方式...

相關的說明與介紹,請參考底下影片:


7 則留言:

Pajace Chen 提到...

原來如此, 難怪我一直無法好好控制 await 和 async, 老是無法捉模他的行為... 現在我懂了!!感謝老師的分享!!

David 提到...

my pleasure, Hope this helps.

Pajace 提到...

David 老師你好, 請問我仿照你的方式去操作 await 和 async, 只是我改用開檔讀檔. 可是我發現, 如果我是用 call method 然後回傳 Task 的方式, 在呼叫該 method 時不加上 awiat 他就會出現

Start()

System.Threading.Task`1[System.String]

Finish(),

若是不把讀檔另外寫在 method 中, 直接呼叫他就會出現

Start()

System.__ComObject

Finish().

想請問老師, 我是有什麼地方漏掉嗎?謝謝!!

Pajace 提到...

Hi David 老師你好, 我發現問題點了, 原來 async 只是要讓 compiler 知道這個 method 中會有 await 出現, 並且會照順序執行(會等). 所以並不代表說這個 method 就是 awaitable, 必須這個 method 要有回傳 Task 或 Task 才代表這個 method 是 awaitable 的. 應該是這樣吧!^^"

David 提到...

Hi Pajace,

首先,async 只是為了讓 compiler 知道可以在這個 method 中,針對有 await 出現的地方幫你加上斷點,跟這個你自己寫的Method是否可以透過await(也就是它是否為awaitable)沒有直接的關係。

讓你的Method可以使用await呼叫的原因是該Method的型別為Task<...>,在範例中我用的Task,是因為我的Method的回傳值是String, 若你自己設計的Method有回傳值,必須要依照你的回傳值的型別,寫成Task這樣才行。

Pajace 提到...

恩恩!我清楚了!!非常謝謝 David 老師~~~

匿名 提到...

David 您好,

剛看到您展示的第一段程式碼中,在GetRemoteData()中存取的TextBox1.Text,這樣與介面的藕合程度過高,因此您的第二段程式碼是比較有範例價值的。

但是問題是如何在第二段的使用基礎上,來產生第一段的效果(Start→Finish→時間),因為拿掉await會造成TASK的回傳錯誤,不知這方面是否可以請較您開示一下簡單的寫法呢?