【问题标题】:Await vs Task.Result in an Async Method [duplicate]异步方法中的 Await vs Task.Result [重复]
【发布时间】:2015-11-21 06:17:59
【问题描述】:

执行以下操作有什么区别:

async Task<T> method(){
    var r = await dynamodb.GetItemAsync(...)
    return r.Item;
}

async Task<T> method(){
    var task = dynamodb.GetItemAsync(...)
    return task.Result.Item;
}

就我而言,出于某种原因,只有第二个有效。第一个似乎永远不会结束。

【问题讨论】:

标签: c# asynchronous async-await task amazon-dynamodb


【解决方案1】:

task.Result 正在访问属性的 get 访问器阻塞调用线程,直到异步操作完成;相当于调用Wait method。 一旦操作的结果可用,它就会被存储并在后续调用 Result 属性时立即返回。请注意,如果在任务运行过程中发生异常,或者如果任务已被取消,则 Result 属性不会返回值。相反,尝试访问属性值会引发 AggregateException 异常。 唯一的区别是 await 不会阻塞。相反,它将异步等待任务完成然后恢复

【讨论】:

  • 为什么在这种情况下等待不起作用,但结果确实起作用
  • 调用Result bare 是一个隐藏的死锁。
  • 捎带 Joshua,你可以在这里找到更多关于它为什么会导致隐藏死锁的信息:stackoverflow.com/questions/17248680/…
【解决方案2】:

await 异步解包任务的结果,而仅使用 Result 会阻塞,直到任务完成。

See this explanantion from Jon Skeet.

【讨论】:

  • 为什么在这种情况下等待不起作用,但结果确实起作用
  • @luis:缺少任何其他信息,我看到的唯一答案是它实际上不适用于await 案例。你只是错误地认为它确实是因为方法本身返回。但是正在等待的任务可能不会以任何方式完成。如果您想要 that 的答案(这与您提出的问题不同),您需要发布一个新问题,清楚地说明这一点,并提供可靠地重现问题的 a good, minimal, complete code example
  • 调用Result bare 是一个隐藏的死锁。
  • 这篇文章有点老了,但你做了await Method() 吗?
  • @user2953241: .Result 或其所有可能的变体导致线程池线程等待线程池上的作业完成。这可能会耗尽线程池上的所有线程,而没有一个线程可以执行实际工作。
猜你喜欢
  • 1970-01-01
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-24
  • 2017-05-14
  • 1970-01-01
相关资源
最近更新 更多