我很好奇 async
的流程是如何在整个堆栈中工作的。在阅读 C# 中的 async
时,您将不断阅读以下内容的某些版本:
If the task we are awaiting has not yet completed then sign up the rest of this method as the continuation of that task, and then return to your caller immediately; the task will invoke the continuation when it completes.
让我感到困惑的是立即返回调用者部分。在下面的示例中,假设调用了 MethodOneAsync()
,执行命中了 MethodOneAsync
中的 await。它会立即返回调用它的方法吗?如果是这样,MethodTwoAsync
是如何执行的?或者它是否继续向下堆栈直到它检测到它实际上被阻止(即 DoDBWorkAsync()
)然后让出线程?
public static async Task MethodOneAsync()
{
DoSomeWork();
await MethodTwoAsync();
}
public static async Task MethodTwoAsync()
{
DoSomeWork();
await MethodThreeAsync();
}
public static async Task MethodThreeAsync()
{
DoSomeWork();
await DoDBWorkAsync();
}
最佳答案
async
方法中await
之前的部分是同步执行的。所有 async
方法都是这种情况。
让我们假设 await DoDBWorkAsync()
我们有 await Task.Delay(1000)
。
这意味着 MethodOneAsync
开始运行,执行 DoSomeWork
并调用 MethodTwoAsync
进而执行 DoSomeWork
调用 MethodThreeAsync
再次执行 DoSomeWork
。
然后它调用 Task.Delay(1000)
,返回一个未完成的 Task
并等待它。
await 在逻辑上等同于添加一个延续并将任务返回给调用者,这是 MethodTwoAsync
做同样的事情并返回一个 Task
给调用者和等等。
这样,当根延迟 Task
完成时,所有的延续都可以一个接一个地运行。
如果我们让你的例子更复杂一点:
public static async Task MethodOneAsync()
{
DoSomeWorkOne();
await MethodTwoAsync();
DoMoreWorkOne();
}
public static async Task MethodTwoAsync()
{
DoSomeWorkTwo();
await MethodThreeAsync();
DoMoreWorkTwo();
}
public static async Task MethodThreeAsync()
{
DoSomeWorkThree();
await Task.Delay(1000);
DoMoreWorkThree();
}
这在逻辑上类似于使用延续来执行此操作:
public static Task MethodOneAsync()
{
DoSomeWorkOne();
DoSomeWorkTwo();
DoSomeWorkThree();
return Task.Delay(1000).
ContinueWith(_ => DoMoreWorkThree()).
ContinueWith(_ => DoMoreWorkTwo()).
ContinueWith(_ => DoMoreWorkOne());
}
关于c# - 通过堆栈的异步/等待行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29502520/