Is Task.Result the same as .GetAwaiter.GetResult()?

async-await, c#

Solution

`Task.GetAwaiter().GetResult()` is preferred over `Task.Wait` and `Task.Result` because it propagates exceptions rather than wrapping them in an `AggregateException`. However, all three methods cause the potential for deadlock and thread pool starvation issues. They should all be avoided in favor of `async/await`.

The quote below explains why `Task.Wait` and `Task.Result` don't simply contain the exception propagation behavior of `Task.GetAwaiter().GetResult()` (due to a "very high compatibility bar").

As I mentioned previously, we have a very high compatibility bar, and thus we’ve avoided breaking changes. As such, `Task.Wait` retains its original behavior of always wrapping. However, you may find yourself in some advanced situations where you want behavior similar to the synchronous blocking employed by `Task.Wait`, but where you want the original exception propagated unwrapped rather than it being encased in an `AggregateException`. To achieve that, you can target the Task’s awaiter directly. When you write “`await task;`”, the compiler translates that into usage of the `Task.GetAwaiter()` method, which returns an instance that has a `GetResult()` method. When used on a faulted Task, `GetResult()` will propagate the original exception (this is how “`await task;`” gets its behavior). You can thus use “`task.GetAwaiter().GetResult()`” if you want to directly invoke this propagation logic.

https://devblogs.microsoft.com/pfxteam/task-exception-handling-in-net-4-5/

“`GetResult`” actually means “check the task for errors”

In general, I try my best to avoid synchronously blocking on an asynchronous task. However, there are a handful of situations where I do violate that guideline. In those rare conditions, my preferred method is `GetAwaiter().GetResult()` because it preserves the task exceptions instead of wrapping them in an `AggregateException`.

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

Problem

I was recently reading some code that uses a lot of async methods, but then sometimes needs to execute them synchronously. The code does: ``` Foo foo = GetFooAsync(...).GetAwaiter().GetResult(); ``` Is this the same as ``` Foo foo = GetFooAsync(...).Result; ```

Original source

Related problems