jah*_*hav 3 .net c# asynchronous async-await
当我有两个任务并等待一个任务时,我无法理解控制流程.异步程序(C#和Visual Basic)中的控制流只使用一个等待,所以它没有帮助.
我有以下代码:
public async Task Loop(string name, int count)
{
for (int i = 0; i < count; i++)
{
Console.WriteLine("{0}: {1} Before", name, i);
await Task.Delay(10);
Console.WriteLine("{0}: {1} After", name, i);
}
Console.WriteLine("{0} COMPLETE", name);
}
[TestMethod]
public async Task TwoLoopsWithSeparateAwait()
{
var loopOne = Loop("ONE", 3);
Console.WriteLine("After ONE Creation");
var loopTwo = Loop("TWO", 3);
Console.WriteLine("After TWO Creation, before ONE await");
await loopOne;
Console.WriteLine("After ONE await");
await loopTwo;
Console.WriteLine("After TWO await");
}
Run Code Online (Sandbox Code Playgroud)
结果如下:
根据await(C#参考):
await表达式不会阻止它正在执行的线程.相反,它会导致编译器将其余的异步方法注册为等待任务的延续.然后,Control返回到异步方法的调用者.当任务完成时,它会调用它的继续,异步方法的执行从它停止的地方恢复.
我理解在等待loopOne之前会发生什么,但我认为只有loopOne会被执行(可能是同步的),看起来await的行为更像是一个可以继续保存可能任务列表的yield(我认为它符合"当任务时"完成后,它会调用它的继续").
在等待多个任务期间,控制流程背后的逻辑是什么?
一个async方法同步执行,直到达到await.然后,它创建一个任务,代表async您正在等待的操作以及其余代码,作为操作完成时执行的延续.这意味着在async第一个await到达时的方法中,控件实际上通过热任务返回给调用者.当await在该延续内部达到a时,它再次注册延续等等.
所以在你的情况下,执行顺序应该是:
根据异步操作实际花费的时间长短,中间的延续可以很容易地处于不同的顺序.
你可以想象这里有3种不同的流程.第一个执行两个Loop调用的同步部分,启动2个并发的async操作流和continuation,然后在第一个调用中注册一个continuation,它将向第二个调用注册一个continuation.