Blocking on async code can cause deadlocks C# with Example
It is a bad practice to block on async calls as it can cause deadlocks in environments that have a synchronization context. The best practice is to use async/await "all the way down." For example, the following Windows Forms code causes a deadlock: private async Task TryThis() { Trace.TraceInformation("Starting TryThis"); await Task.Run(() => { Trace.TraceInformation("In TryThis task"); for (int i = 0; i < 100; i++) { // This runs successfully - the loop runs to completion Trace.TraceInformation("For loop " + i); System.Threading.Thread.Sleep(10); } }); // This never happens due to the deadlock Trace.TraceInformation("About to return"); return true; } // Button click event handler private void button1_Click(object sender, EventArgs e) { // .Result causes this to block on the asynchronous call bool result = TryThis().Result; // Never actually gets here Trace.TraceInformation("Done with result"); } Essentially, once the async call completes, it waits for the synchronization context to become available. However, the event handler "holds on" to the synchronization context while it's waiting for the TryThis() method to complete, thus causing a circular wait. To fix this, code should be modified to private async void button1_Click(object sender, EventArgs e) { bool result = await TryThis(); Trace.TraceInformation("Done with result"); } Note: event handlers are the only place where async void should be used (because you can't await an async void method). Async-Await