C# – async/await簡介

1. async方法回傳值為Task, Task<T>或void。
注意: void要小心使用,比較好的作法是只用在事件處理的方法上(eg: protected async void LoadOrders_Click(object sender, EventArgs e))
async和await必須同時使用,如果標示方法為async卻沒有await,將只會以同步方式執行

2.awaitable方法表示最耗時的部分,我們希望它可以在獨立的task thread中執行,因此將其包在Task如下:
Task<IEnumerable<Order>>.Run(() => { return orderHandler.GetAllOrders(); });

同步取得訂單的方法:
protected async void LoadOrders_Click(object sender, EventArgs e)) //這裡標示async沒效果
{
var orders = orderHandler.GetAllOrders();
}
改成非同步取得訂單的方法:
protected async void LoadOrders_Click(object sender, EventArgs e)
{
var orders = await Task<IEnumerable<Order>>.Run(() => { return orderHandler.GetAllOrders(); });
}

3.上面非同步方法主thread的orders還是會等,因此我們將取得訂單移至新的方法:
protected async void LoadOrders_Click(object sender, EventArgs e)
{
Task<IEnumerable<Order>> LoadOrders = doLoadOrder(); //1.交給task thread執行,但不急著取回傳值
//3.做一些其他事…
var order = await LoadOrders; //4.這時才取task thread的回傳值
//6.處理order
}

private async Task<IEnumerable<Order>> doLoadOrder()
{
var order = await Task<IEnumerable<Order>>.Run(() => { return orderHandler.GetAllOrders(); }); //2.耗時的部份已移至此task thread,主控權還給主thread
return order; //5.回傳結果
}

4.修改一下流程,讓task thread結束時通知主thread,而不要讓主thread去等order結果,因此我們將doLoadOrder改為void (not awaitable):
protected void LoadOrders_Click(object sender, EventArgs e) //async可以拿掉了
{
doLoadOrder(); //1.交給task thread執行,結束時再通知主thread接手
//3.做一些其他事…
}

private async void doLoadOrder() //改為void要小心控制流程!
{
var order = await Task<IEnumerable<Order>>.Run(() => { return orderHandler.GetAllOrders(); }); //2.耗時的部份已移至此task thread,主控權還給主thread
//4.通知主thread處理order
}

整理自: http://www.oschina.net/translate/csharp-5-0-async-and-await
http://msdn.microsoft.com/zh-tw/library/hh191443.aspx

廣告