How to Run Async Method Synchronously in C#
GetAwaiter().GetResult() or accessing the Result property of the task. These methods block the current thread until the async operation completes, allowing synchronous code to wait for async results.Syntax
To run an async method synchronously, you typically call the async method and then use either GetAwaiter().GetResult() or .Result on the returned Task. This blocks the current thread until the async method finishes and returns the result.
asyncMethod().GetAwaiter().GetResult(): Waits for the task to complete and unwraps exceptions.asyncMethod().Result: Waits for the task and returns the result but may wrap exceptions inAggregateException.
var result = AsyncMethod().GetAwaiter().GetResult(); // or var result = AsyncMethod().Result;
Example
This example shows how to call an async method that returns a string and run it synchronously using GetAwaiter().GetResult(). It prints the result after waiting for the async operation.
using System; using System.Threading.Tasks; class Program { static async Task<string> GetGreetingAsync() { await Task.Delay(500); // Simulate async work return "Hello from async method!"; } static void Main() { // Run async method synchronously string greeting = GetGreetingAsync().GetAwaiter().GetResult(); Console.WriteLine(greeting); } }
Common Pitfalls
Running async methods synchronously can cause deadlocks, especially in UI or ASP.NET contexts where a synchronization context exists. Using .Result or .Wait() can wrap exceptions in AggregateException, making error handling harder.
Prefer GetAwaiter().GetResult() to avoid exception wrapping. Avoid blocking on async code in UI threads to prevent freezing.
/* Wrong way - may cause deadlock and wraps exceptions */ // string result = AsyncMethod().Result; /* Better way - unwraps exceptions and reduces deadlock risk */ // string result = AsyncMethod().GetAwaiter().GetResult();
Quick Reference
| Method | Description | Notes |
|---|---|---|
| GetAwaiter().GetResult() | Blocks until async completes and unwraps exceptions | Preferred for synchronous calls |
| .Result | Blocks until async completes but wraps exceptions in AggregateException | Use with caution |
| .Wait() | Blocks until async completes, returns void, wraps exceptions | Not recommended for getting results |
| Avoid blocking on UI thread | Can cause deadlocks | Use async all the way if possible |