When you use Task.Run
, the initial synchronous part of your delegate is run on a threadpool thread, whereas just ().GetAwaiter().GetResult()
will run that synchronous part on the same thread.
Using Task.Run(...).GetAwaiter().GetResult()
can be used as a workaround to run async code and wait on it synchronously, it will not result in an async deadlock, whereas ().GetAwaiter().GetResult()
could. Do be aware that it still isn't "safe", in that you likely are blocking within a threadpool thread, on servers this can lead to thread pool exhaustion at load.
If you want to run a Task
returning method, and know that the initial synchronous part is trivial, and you know that the rest of the async method will not run with a SynchronizationContext
, just ().GetAwaiter().GetResult()
can be a micro-optimization, I'd say only do it if you know exactly what you are doing.
How do you know that you are running under no SynchronizationContext
? SynchronizationContext.Current
will be null
, due to one the following reasons:
- You know your code is running under an application model that doesn't have one (Console app, ASP.NET Core, Windows Service)
- You have used
.ConfigureAwait(false)
on an awaited incomplete Task
previously in the current stack.
- You have explicitly called
SynchronizationContext.SetSynchronizationContext(null)
So you see, it's a lot to think about, so in general you almost always want to use Task.Run(...).GetAwaiter.GetResult()
.