摘要:[asp.net]簡易async, await非同步範例(framework 4.5才有)
以下來自網路的文章的片段翻譯: 實際做事的function不要加上任何非同步的修飾文字(例如:async, await, task.run,task.delay.....)
而是把這些修飾的文字使用在呼叫這個function的caller端,作者建議如果是asp.net程式,要盡量少用非同步的寫法
避免造成伺服器負擔
//簡易的async, await範例
protected async void btnSampleAsyncCallNonAync_Click(object sender, EventArgs e)
{
long longResult = 0;
longResult = await Task.Run(() => GetSumSync());
Page.ClientScript.RegisterStartupScript(this.GetType(), "", "alert('sum=" + longResult.ToString() + "');", true);
}
//正統implement function不加入任何的threading機制
private long GetSumSync()
{
long longSum = 0;
for (long i = 0; i < 100000; i++)
{
longSum += i;
}
return longSum;
}
如果很不幸的,你需要呼叫網路上提供的function,而且這個function只有提供非同步版本的,該怎麼執行呢?
非同步的執行此function的範例:
//不見得每個人都知道implement function要盡量避免用threading,而是要在call端才去決定是否用threading
//如果碰到了網路上提供的function是非同步的話怎麼辦呢
//如何非同步的呼叫網路上提供的 非同步async implement function
protected async void btnSampleAsyncCallAsync_Click(object sender, EventArgs e)
{
long longResult = 0;
longResult = await GetSumAsync();
Page.ClientScript.RegisterStartupScript(this.GetType(), "", "alert('sum=" + longResult.ToString() + "');", true);
}
//此implement function加入的threading機制,雖然不應該,但是這是網路上提供的,也只能用了
private async Task GetSumAsync()
{
long longSum = 0;
await Task.Run(() =>
{
for (long i = 0; i < 100000; i++)
{
longSum += i;
}
});
return longSum;
}
同樣的網路上提供的非同步的function(對方無提供同步版本的function),如果你希望用同步的方式去執行,該怎麼做呢?
//以同步的方式去呼叫網路上提供的非同步方法,按照msdn的解釋
//該function將會強制被改回同步執行
protected void btnSampleSyncCallAsync_Click(object sender, EventArgs e)
{
//long longResult = 0;
//硬要改成同步執行的話,回傳的型態不是long, 而是Task
//根據Stephen的說法,也是要極力避免,因為會造成Deadlock
//http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
//根據msdn的說法,也是要極力避免同步的方式去呼叫非同步的方式(文長未細看)
//http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx
//但是在不可避免的情況下,msdn建議可以利用Task.Run去做到這點
Task t = Task.Run(() => GetSumAsync());
//結果要用Task.Result去解開
//如果回傳value是單純的Task,要加上
//Task.WaitAll(t);
Page.ClientScript.RegisterStartupScript(this.GetType(), "", "alert('sum=" + t.Result.ToString() + "');", true);
}
//GetSumAsync()跟上一個例子一樣,在此就不重複附上
範例程式下載(研究GitHub程式碼線上控管中,之後補上):
專案ConcurrencyWebForm的BasicSampleAsyncAwait.aspx
參考文章:
Task.Run Etiquette Examples: Don't Use Task.Run in the Implementation
http://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-dont-use.html
Should I expose synchronous wrappers for asynchronous methods?
http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx