据我所知,yield关键字,如果从迭代器块内部使用,它会将控制流返回给调用代码,当再次调用迭代器时,它会从中断处继续.
此外,await不仅等待被调用者,而且还将控制权返回给调用者,仅在调用者调用awaits方法时从中断处获取.
换句话说 - 没有线程,async和await的"并发"是一种由巧妙的控制流引起的错觉,其细节被语法隐藏.
现在,我是一名前汇编程序员,我对指令指针,堆栈等非常熟悉,并且我得到了正常的控制流(子程序,递归,循环,分支)的工作方式.但是这些新的结构 - 我没有得到它们.
当await到达,如何运行时知道什么是一段代码接下来应该执行?它是如何知道什么时候可以从它停止的地方恢复的,它如何记住在哪里?当前的调用堆栈会发生什么,它会以某种方式保存吗?如果调用方法在其之前进行其他方法调用,那么该await怎么办?为什么堆栈不会被覆盖呢?在异常和堆栈展开的情况下,运行时如何在所有这些中运行?
何时yield到达,运行时如何跟踪应该拾取事物的点?迭代器状态如何保存?
我有一个异步asp.net控制器.该控制器调用异步方法.实际执行异步IO工作的方法深入到我的应用程序中.控制器和链中最后一个方法之间的一系列方法都用async修饰符标记.以下是我如何设置代码的示例:
public async Task<ActionResult> Index(int[] ids)
{
List<int> listOfDataPoints = dataPointService(ids);
List<Task> dpTaskList = new List<Task>();
foreach (var x in listOfDataPoints)
{
dpTaskList.Add(C_Async(x));
}
await Task.WhenAll(dpTaskList);
return View();
}
private async Task C_Async(int id)
{
//this method executes very fast
var idTemp = paddID(id);
await D_Async(idTemp);
}
private async Task D_Async(string id)
{
//this method executes very fast
await E_Async(id);
}
private async Task E_Async(string url)
{
//this method performs the actual async IO
result = await new WebClient().DownloadStringTaskAsync(new Uri(url)) …Run Code Online (Sandbox Code Playgroud)