2

when we have a call like this:

Database.ExecuteSqlRawAsync(sql, parameters);

we can await it:

await Database.ExecuteSqlRawAsync(sql, parameters);

which is great.

But what is the point of .Result?

Database.ExecuteSqlRawAsync(sql, parameters).Result;

When would this be of any use?

jason.kaisersmith
  • 8,712
  • 3
  • 29
  • 51
CraftyFox
  • 165
  • 2
  • 11
  • 3
    To [deadlock your program](https://stackoverflow.com/questions/73919716/tararchive-hangs-when-trying-to-extract-contents)... More seriously, it is being used to use async methods (Task-returning methods) in a synchronous, blocking manner. However, using it nilly-willy without understanding the peculiar and complicated details of continuation execution contexts can lead to deadlocks depending on the type of application and other factors... –  Oct 04 '22 at 09:03
  • 2
    _"When would this be of any use?"_ - `.Result` is used to _synchronously_ return the result value `T` from a `Task` when _you know_ it has completed successfuly so the `.Result` property won't hang, deadlock, block, or anything sinister like that. – Dai Oct 04 '22 at 09:05
  • 1
    Another point is that the design of `Task`, including its blocking `.Result` property, were added in .NET Fx 4.0, which was 2 years before `async`/`await` was added to C# and when the TPL was more about `Parallel.For` and the thread-pool so I don't think anyone was concerned about deadlocking back then - assuming it was even possible for some `TaskCompletionSource` scenarios... – Dai Oct 04 '22 at 09:15

2 Answers2

4

The first case would be when you want to wait synchronously for the result. This is not recommended, due to the potential of deadlocks, but the possibility is available if you really need it.

Another use case is when using something like Task.WhenAll. This does not return a result when awaiting, so you need another way to get to the result of each individual task. Since you are sure all the tasks are completed it does not really matter if you use await task or task.Result.

JonasH
  • 28,608
  • 2
  • 10
  • 23
0

Asynchronous methods return Task objects (or Task<T> objects). All Task objects provide the .Result property to allow us to wait for tasks to complete synchronously.

Generally you should await tasks instead of using the .Result property as using .Result blocks the calling thread.

You can use .Result if you need to utilise an asynchronous method from a synchronous method/context.

Result can also be used to access the result of a finished task without blocking the calling thread (e.g. after awaiting a Task.WhenAll call as mentioned by @JonasH).

YungDeiza
  • 3,128
  • 1
  • 7
  • 32