(我已经阅读了很多关于异步的内容,我想知道如果有异步函数调用和非异步混合会发生什么)并且我正在谈论 THREAD pov 。
(我知道混合不应该完成,但我要求更好地理解流程)
假设我有(立方体1)函数调用async函数调用asyc函数。
(请注意,立方体1功能不是异步)
问题:当控制到达(立方体3)await Task.Delay(100);
-
当控制到达 cube3 await
时,真正发生了什么?控制是在粉红色箭头(立方体1)处返回(和阻止),还是控件被释放并仍在等待(橙色箭头)
答案 0 :(得分:2)
当控件到达await
中的Cube3
语句时,会调用Task.Delay()
并立即返回将在延迟后完成的Task
。 CalculateAnswer()
的其余部分将重构为一个延续,该延续将在Task
返回的Delay()
完成时运行,CalculateAnswer()
会立即返回Task<int>
时将完成的CallCalculateAnswer()
继续完成。
Task<int>
等待CalculateAnswer()
返回的await
,因此适用相同的逻辑:在return
之后运行的代码(即Task<int>
语句)是重构为在CallCalculateAnswer()
完成时运行的延续,Task<int>
继续返回自己的StartChain()
。
Task<int>
不等待CallCalculateAnswer()
生成的Task<int>
,因此不会生成延续。相反,它将任务存储到局部变量中并返回。因此,问题中的橙色箭头是正确的。
请注意,在这种特定情况下,由于CallCalculateAnswer()
返回的StartChain()
没有任何操作,并且它只存储在一个局部变量中,因此它会被遗忘&#34;一旦int
返回:任务将在未来某个时间完成(或失败),但其结果(它产生的StartChain()
)将丢失。
更新以下评论:您问题中的粉红色箭头表示您希望CallCalculateAnswer()
阻止,等待async
返回的任务完成,因为它不是await
,也不是StartChain()
该任务。这不是发生的事情,因为通常的控制流语义适用:该方法返回了一个任务,因此您只能获得对该任务的引用。
如果您希望屏蔽CallCalculateAnswer()
,可以对{{1}}返回的任务使用Task.Wait(),Task<T>.Result
或类似内容。