我非常好奇async/await如何使你的程序不会停顿。我真的很喜欢Stephen Cleary解释async/await的方式:"我喜欢把“await”看作是“异步等待”。也就是说,异步方法会暂停,直到可等待对象完成(所以它在等待),但实际线程没有被阻塞(所以它是异步的)"
我读过async方法在编译器遇到await关键字之前是同步工作的。如果编译器无法找到awaitable对象,那么编译器就将awaitable对象排队,并将控制权交给调用AccessTheWebAsync方法的方法。在这个例子中,调用者(事件处理程序)会继续处理。调用方可能会做一些与AccessTheWebAsync方法结果无关的其他工作,然后再等待该结果,或者立即等待该结果。事件处理程序正在等待AccessTheWebAsync方法,而AccessTheWebAsync方法正在等待GetStringAsync方法。让我们看一个MSDN示例:
async Task<int> AccessTheWebAsync()
{
// You need to add a reference to System.Net.Http to declare client.
HttpClient client = new HttpClient();
// GetStringAsync returns a Task<string>. That means that when you await the
// task you'll get a string (urlContents).
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();
// The await operator suspends AccessTheWebAsync.
// - AccessTheWebAsync can't continue until getStringTask is complete.
// - Meanwhile, control returns to the caller of AccessTheWebAsync.
// - Control resumes here when getStringTask is complete.
// - The await operator then retrieves the string result from getStringTask.
string urlContents = await getStringTask;
// The return statement specifies an integer result.
// Any methods that are awaiting AccessTheWebAsync retrieve the length value.
return urlContents.Length;
}
微软开发团队的另一篇博客文章指出async/await不会创建新的线程或使用线程池中的其他线程。好的。
我的问题:
在我们的例子中,async/await在哪里执行可等待的代码(例如下载网站),导致控制权让程序转而询问
Task<string> getStringTask
的结果?我们知道没有新线程,也没有使用线程池。我这个傻瓜的假设是否正确,即CLR只是在一个线程范围内在当前可执行代码和可等待方法之间切换?但更改加数的顺序不会改变总和,UI可能会被阻塞一段时间。