async(with non-async)功能控制流程澄清?

时间:2013-07-14 07:53:04

标签: .net-4.5 async-await c#-5.0

(我已经阅读了很多关于异步的内容,我想知道如果有异步函数调用和非异步混合会发生什么)并且我正在谈论 THREAD pov

(我知道混合不应该完成,但我要求更好地理解流程)

假设我有(立方体1)函数调用async函数调用asyc函数。

(请注意,立方体1功能不是异步)

问题:当控制到达(立方体3)await Task.Delay(100); -

当控制到达 cube3 await时,真正发生了什么?控制是在粉红色箭头(立方体1)处返回(和阻止),还是控件被释放并仍在等待(橙色箭头)

enter image description here

1 个答案:

答案 0 :(得分:2)

当控件到达await中的Cube3语句时,会调用Task.Delay()并立即返回将在延迟后完成的TaskCalculateAnswer()的其余部分将重构为一个延续,该延续将在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或类似内容。