在玩过 .NET 4.5 async\await 框架后,我有一个问题。
让我们看一下这个程序(msdn 示例):
async Task<int> AccessTheWebAsync()
{
HttpClient client = new HttpClient();
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
DoIndependentWork();
string urlContents = await getStringTask;
return urlContents.Length;
}
void DoIndependentWork()
{
resultsTextBox.Text += "Working . . . . . . .\r\n";
}
该程序将按以下顺序运行:
- 新的 HttpClient。
- GetStringAsync 同步调用。
- 在某些时候,GetStringAsync 调用 await 并且控件返回到 AccessTheWebAsync。
- 调用了 DoIndependentWork。
- 程序等待返回的字符串(如果操作未完成则阻塞)。
- 返回 urlContent 的长度。
我花了一段时间才理解的一件事是,GetStringAsync
尽管它的名称该方法是同步运行的(名称约定确实具有误导性)。
为了异步运行该方法,我们需要显式使用Task.Run
or Task.Factory.StartNew
。
但真正的问题是,如果我们有独立的工作,为什么不马上做,而不是等待从 GetStringAsync 调用 await?(换句话说,为什么 async 方法不能按照定义异步运行?)
编辑: 我将改写第二个和第三个操作:
(2) GetStringAsync 同步启动。
(3) 在某些时候,GetStringAsync 调用 await 并且线程分叉,控制返回到 AccessTheWebAsync。