Task.Result与.GetAwaiter.GetResult()相同吗?

我最近正在阅读一些使用大量asynchronous方法的代码,但有时候需要同步执行它们。 代码确实:

Foo foo = GetFooAsync(...).GetAwaiter().GetResult(); 

这是一样的

 Foo foo = GetFooAsync(...).Result; 

很多。 一个小的区别:如果Task失败, GetResult()将直接引发exception,而Task.Result将抛出一个AggregateException 。 然而,当它是async的时候,使用其中的哪一个有什么意义? 100倍更好的select是使用await

另外,你不打算使用GetResult() 。 这意味着仅供编译器使用,而不是为了您。 但是,如果你不想讨厌的AggregateException ,使用它。

https://github.com/aspnet/Security/issues/59

“最后一句话:你应该尽量避免使用Task.ResultTask.Wait ,因为它们总是把内部exception封装在一个AggregateException并用一个通用的(发生一个或多个错误)replace消息,这使得debugging更加困难即使不应该经常使用同步版本,也应该考虑使用Task.GetAwaiter().GetResult()来代替。

http://blog.stephencleary.com/2014/12/a-tour-of-task-part-6-results.html

GetResult ”实际上是指“检查任务是否有错误”

一般来说,我尽我所能避免同步阻塞asynchronous任务。 但是,有一些情况我违反了这个准则。 在这些罕见的情况下,我首选的方法是GetAwaiter().GetResult()因为它保留了任务exception,而不是将它们包装在一个AggregateException

http://blogs.msdn.com/b/pfxteam/archive/2011/09/28/task-exception-handling-in-net-4-5.aspx

正如我前面提到的,我们有一个非常高的兼容性,因此我们避免了变化。 因此, Task.Wait保留了始终包装的原始行为。 但是,您可能会发现自己处于某些高级情况,您希望类似于Task.Wait使用的同步阻塞的Task.Wait ,但是希望将原始exception传播到未包装的位置,而不是将其封装在AggregateException 。 为了达到这个目的,你可以直接定位任务的服务器。 当你写“ await task; “,编译器将其翻译成Task.GetAwaiter()方法的用法,该方法返回一个具有GetResult()方法的实例。 当在一个有故障的Task上使用时, GetResult()会传播原来的exception(这是“ await task; ”的方式)。 如果你想直接调用这个传播逻辑,你可以使用“ task.GetAwaiter().GetResult() ”。

另一个区别是, async函数只返回Task而不是Task<T>那么你不能使用

 GetFooAsync(...).Result; 

 GetFooAsync(...).GetAwaiter().GetResult(); 

仍然有效。

我知道问题中的示例代码是针对案例Task<T> ,但是一般会问到这个问题。