我只是对C#的异步编程有一些基本的了解。据我了解,这段代码
statement1;
await statement2();
statement3;
statement4;
在逻辑上应等效于
statement1;
var awaiter = statement2().GetAwaiter();
awaiter.OnCompletion(() => {
awaiter.GetResult();
statement3;
statement4;
});
因此,如果await
代码中有一条语句,则以下所有语句仅在等待的任务完成后才开始执行。这似乎就像同步代码。该文档指出,该await
语句将导致执行返回给调用者,并在等待的任务完成后恢复执行。但是在下面的示例中,我无法完全理解它是如何工作的。
using System;
using System.Threading.Tasks;
namespace ThreadTesting
{
class Program
{
public static async Task Main(string[] args)
{
await DoSomething2(); // <------- B
Console.WriteLine("Test!"); // <------- C
Console.ReadKey(); // <------- D
}
public static async Task DoSomething2()
{
Console.WriteLine("Start DoSomething2");
var i = await DoSomething(); // <------ A
Console.WriteLine("End DoSomething2");
}
public static async Task<int> DoSomething()
{
Console.WriteLine("Start DoSomething1");
await Task.Delay(10000);
Console.WriteLine("Before returning from DoSomething1");
return 88;
}
}
}
输出是
Start DoSomething2
Start DoSomething1
Before returning from DoSomething1
End DoSomething2
Test!
让我们以语句A为例。在这里等待DoSomething()
。在等待时,执行逻辑从DoSomething2()
B返回并返回到B。据我所知,执行应在等待时继续执行语句C和D DoSomething2()
(语句B)。但是结果表明该字符串"Test!"
仅在程序末尾打印。为什么会这样?我的理解正确吗?
要注意的是您的Main
回报Task
,因此它也async
将被完全“阻止”。您的执行顺序将如下所示:
Main()
开始await
运算符,并Task
使用其余方法创建一个。看起来好像Main()
已经停止,正在等待await
结果DoSomething2()
启动并写入控制台“ Start DoSomething2”await
运算符,并Task
使用其余DoSomething()
方法创建另一个运算符DoSomething()
开始awat
操作员并Task
使用其余DoSomething()
方法创建一个,等待延迟。Task
操作后(经过延迟),DoSomething()
将“从DoSomething1返回之前”写入控制台并返回88。Task
创建的,DoSomething2()
完成了方法的其余部分(将88分配i
给控制台,并将“从DoSomething1返回之前”写入控制台Task
,在创建Main()
完成,写“测试!” 进行控制台。因此,“测试!” 最后是因为你的Main()
回报Task
。如果您想要该行为,则可以期望将其交换Task
为void
:
public static async void Main(string[] args)
{
...
}
然后,当到达await
操作员位置时,Main()
不会等待Task()
完成并继续执行。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句