(我读过很多关于异步的内容,我想知道如果混合使用异步函数调用和非异步会发生什么),我正在谈论 THREAD pov 。
(我知道不应该进行混合,但我问是为了更好地理解流程)
假设我有(cube 1)函数,它调用异步函数,而异步函数又调用 asyc 函数。
(请注意,Cube 1 函数不是异步的)
问题:当控件到达(立方体 3)时 await Task.Delay(100);
--
当控件到达cube3 await
时,到底发生了什么?控件是否在粉红色箭头(立方体 1)处返回(并被阻止),或者控件是否被释放并仍在等待(橙色箭头)
最佳答案
当控制权达到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()
返回:任务将在未来某个时间完成(或失败),但其结果(它产生的 int
)将丢失。
更新以下评论:您问题中的粉色箭头表示您期待 StartChain()
阻塞,等待 CallCalculateAnswer()
返回的任务完成,因为它不是 async
并且不 await
那个任务。实际情况并非如此,因为通常的控制流语义适用:该方法已返回一个任务,因此您将获得对该任务的引用,仅此而已。
如果你想要StartChain()
要阻止,您可以使用 Task.Wait() , Task<T>.Result
,或类似 CallCalculateAnswer()
返回的任务.
关于.net-4.5 - 异步(与非异步)函数控制流程澄清?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17637534/