【问题标题】:async ( with non-async) function control flow clarification?异步(非异步)函数控制流说明?
【发布时间】:2013-07-12 07:57:11
【问题描述】:

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

(我知道不应该混合,但我问是为了更好地理解流程)

假设我有(立方体 1)调用异步函数的函数,该函数调用异步函数。

(请注意,cube 1 函数不是异步的)

问题:当控件到达(cube 3)await Task.Delay(100);--

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

【问题讨论】:

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


    【解决方案1】:

    当控制到达Cube3 中的await 语句时,调用Task.Delay() 并立即返回一个Task,该Task 将在延迟后完成。 CalculateAnswer() 的其余部分被重构为一个延续,该延续将在Delay() 返回的Task 完成时运行,CalculateAnswer() 立即返回一个Task<int>,该延续将在该延续完成时完成。

    CallCalculateAnswer() 等待CalculateAnswer() 返回的Task<int>,所以同样的逻辑适用:在await 之后运行的代码(即return 语句)被重构为一个延续,当@ 987654338@ 完成,CallCalculateAnswer() 继续返回它自己的Task<int>

    但是,StartChain() 不会等待由CallCalculateAnswer() 生成的Task<int>,因此不会生成延续。相反,它将任务存储到局部变量中并返回。因此,您问题中的橙色箭头是正确的。

    请注意,在这种特定情况下,由于 CallCalculateAnswer() 返回的 Task<int> 没有做任何事情,并且它只存储在局部变量中,因此一旦 StartChain() 返回,它就会被“遗忘”:任务将完成(或失败)未来某个时间,但其结果(它产生的int)将会丢失。

    更新以下 cmets: 您问题中的粉红色箭头表示您希望 StartChain() 阻止,等待 CallCalculateAnswer() 返回的任务完成,因为它不是 async并且没有await 那个任务。这不是发生的事情,因为通常的控制流语义适用:该方法返回了一个任务,因此您获得了对该任务的引用,仅此而已。

    如果您希望StartChain() 阻止,您可以在CallCalculateAnswer() 返回的任务上使用Task.Wait()Task<T>.Result 或类似名称。

    【讨论】:

    • 当控制到达Cube3中的await语句时,Task.Delay()被调用并立即返回 -----返回到哪里?
    • @Royi,给它的调用者CalculateAnswer(),像往常一样。
    • 不,对于它的直接调用者,就像任何函数调用一样。是什么让您认为在这种情况下控制会跳过执行帧?
    • 我在想只有当 startChain 是异步的时候,橙色才是正确的...
    • 关于这个答案的最后一段:Don't Block on Async Code
    猜你喜欢
    • 2022-01-03
    • 2015-10-05
    • 2022-11-16
    • 1970-01-01
    • 2017-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多