问题描述
在使用async-await的程序中,我的理解是这样的:
In programs utilizing async-await, my understanding is like this:
- 未等待的异步方法将在后台(?)运行,其余代码将在该未等待的方法完成之前继续执行
- 已等待IS的异步方法将等待该方法完成,然后再继续进行下一行代码
下面的应用程序是我写的,用于检查以上陈述是否正确.
The application below was written by me to check if the above statements are correct.
using System;
using System.Threading.Tasks;
namespace ConsoleApp3
{
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Hello World!");
DoJob();
var z = 3;
Console.ReadLine();
}
static async Task DoJob()
{
var work1 = new WorkClass();
var work2 = new WorkClass();
while (true)
{
await work1.DoWork(500);
await work2.DoWork(1500);
}
}
}
public class WorkClass
{
public async Task DoWork(int delayMs)
{
var x = 1;
await Task.Delay(delayMs);
var y = 2;
}
}
}
以下是我的一些观察结果:
Here are some of my observations:
- 不等待
DoJob();
调用.但是,调试器向我展示了DoJob内部的代码正在执行,就像它是普通的非异步方法一样. - 当代码执行到
await work1.DoWork(500);
时,我认为好吧,所以也许现在将保留DoJob
方法,然后var z = 3;
会被执行吗?毕竟,"await"应该离开该方法."实际上,它只是进入DoWork
,而没有离开DoJob
-var z = 3;
仍未执行. - 最后,当执行到达
await Task.Delay(delayMs);
时,剩下DoJob
,而var z = 3;
是到达.之后,执行Delay
之后的代码.
- The
DoJob();
call is not awaited. However, the debugger shows me that the code inside of DoJob is being executed, just as if it was a normal non-async method. - When code execution gets to
await work1.DoWork(500);
, I would think "OK, so maybe now theDoJob
method will be left andvar z = 3;
will be executed? After all, 'await' should leave the method." In reality, it just goes intoDoWork
and doesn't leaveDoJob
-var z = 3;
is still not executed. - Finally, when execution reaches
await Task.Delay(delayMs);
,DoJob
is left, and thevar z = 3;
is reached. After that, code after theDelay
is executed.
我不明白的事情:
- 为什么
等待Task.Delay(delayMs);
离开DoJob
方法,但是await work1.DoWork(500);
却没有? - 我看到
DoJob
正常执行.我以为会在后台完成(也许是通过线程池线程之一?).如果这是一个长时间运行的方法,它看起来可能会阻塞线程,对吗?
- Why does
await Task.Delay(delayMs);
leave theDoJob
method, butawait work1.DoWork(500);
does not? - I see that
DoJob
is executing normally. I thought it would be done in the background (maybe by one of the thread pool threads?). Looks like it could block the thread if it was some long-running method, am I right?
推荐答案
编译器将 async
方法中的代码拆分为多个块.在第一个 await
之前1个,在每个 await
之间的1个,以及在最后一个 await
之后的1个.
The compiler splits the code in an async
method in chunks. 1 before the first await
and 1 between each await
and 1 after the last await
.
执行将在第一个未完成的等待者或方法结束时返回给调用者.
The execution will return to the caller at the first non completed awaiter or the end of the method.
此方法将在完全执行后仅返回完成的 Task
:
This method will only return a completed Task
after fully executed:
async Task M1() => await Task.CompletedTask;
此方法将仅返回不完整的 Task
,该任务将在 Task.Dealy(1000)
返回的 Task
完成时完成:
This method will only return an incomplete Task
that will complete when the Task
returned by Task.Dealy(1000)
is completed:
async Task M2() => await Task.Delay(1000);
这是一个小例子:
static async Task Main(string[] args)
{
var t = TwoAwaits();
Console.WriteLine("Execution returned to main");
await t;
}
private static async Task TwoAwaits()
{
Console.WriteLine("Before awaits");
await Task.CompletedTask;
Console.WriteLine("Between awaits #1");
await Task.Delay(1000);
Console.WriteLine("Between awaits #2");
await Task.Delay(1000);
Console.WriteLine("After awaits");
}
/*
Before awaits
Between awaits #1
Execution returned to main
Between awaits #2
After awaits
*/
这篇关于什么时候“等待"立即离开方法,什么时候不离开?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!