异步方法中的 Await vs Task.Result [重复]
Posted
技术标签:
【中文标题】异步方法中的 Await vs Task.Result [重复]【英文标题】:Await vs Task.Result in an Async Method [duplicate] 【发布时间】: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;
就我而言,出于某种原因,只有第二个有效。第一个似乎永远不会结束。
【问题讨论】:
所以我发现 await 可能挂起的唯一原因是来自下面的 SO 答案。我想我会在这里发表评论以帮助未来的我。 ***.com/questions/13489065/…***.com/questions/9895048/… 试试 await dynamodb.GetItemAsync(...).ConfigureAwait(false) 【参考方案1】:task.Result 正在访问属性的 get 访问器阻塞调用线程,直到异步操作完成;相当于调用Wait method。 一旦操作的结果可用,它就会被存储并在后续调用 Result 属性时立即返回。请注意,如果在任务运行过程中发生异常,或者如果任务已被取消,则 Result 属性不会返回值。相反,尝试访问属性值会引发 AggregateException 异常。 唯一的区别是 await 不会阻塞。相反,它将异步等待任务完成然后恢复
【讨论】:
为什么在这种情况下等待不起作用,但结果确实起作用 调用Result
bare 是一个隐藏的死锁。
捎带 Joshua,你可以在这里找到更多关于它为什么会导致隐藏死锁的信息:***.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
或其所有可能的变体导致线程池线程等待线程池上的作业完成。这可能会耗尽线程池上的所有线程,而没有一个线程可以执行实际工作。以上是关于异步方法中的 Await vs Task.Result [重复]的主要内容,如果未能解决你的问题,请参考以下文章