== Why is this an issue? Making blocking calls to ``++async++`` methods transforms code that was intended to be asynchronous into a blocking operation. Doing so can cause deadlocks and unexpected blocking of context threads. According to the MSDN documentation: ____ The root cause of this deadlock is due to the way ``++await++`` handles contexts. By default, when an incomplete ``++Task++`` is awaited, the current “context” is captured and used to resume the method when the ``++Task++`` completes. This “context” is the current ``++SynchronizationContext++`` unless it’s null, in which case it’s the current ``++TaskScheduler++``. GUI and ASP.NET applications have a ``++SynchronizationContext++`` that permits only one chunk of code to run at a time. When the ``++await++`` completes, it attempts to execute the remainder of the ``++async++`` method within the captured context. But that context already has a thread in it, which is (synchronously) waiting for the ``++async++`` method to complete. They’re each waiting for the other, causing a deadlock. ____ [frame=all] [cols="^1,^1,^1"] |=== |To Do This …|Instead of This …|Use This |Retrieve the result of a background task|``++Task.Wait++``, ``++Task.Result++`` or ``++Task.GetAwaiter.GetResult++``|``++await++`` |Wait for any task to complete|``++Task.WaitAny++``|``++await Task.WhenAny++`` |Retrieve the results of multiple tasks|``++Task.WaitAll++``|``++await Task.WhenAll++`` |Wait a period of time|``++Thread.Sleep++``|``++await Task.Delay++`` |=== === Noncompliant code example [source,text] ---- public static class DeadlockDemo { private static async Task DelayAsync() { await Task.Delay(1000); } // This method causes a deadlock when called in a GUI or ASP.NET context. public static void Test() { // Start the delay. var delayTask = DelayAsync(); // Wait for the delay to complete. delayTask.Wait(); // Noncompliant } } ---- === Compliant solution [source,text] ---- public static class DeadlockDemo { private static async Task DelayAsync() { await Task.Delay(1000); } public static async Task TestAsync() { // Start the delay. var delayTask = DelayAsync(); // Wait for the delay to complete. await delayTask; } } ---- === Exceptions * Main methods of Console Applications are not subject to this deadlock issue and so are ignored by this rule. * ``++Thread.Sleep++`` is also ignored when it is used in a non-``++async++`` method. * Calls chained after ``++Task.Run++`` or ``++Task.Factory.StartNew++`` are ignored because they don't suffer from this deadlock issue == Resources * https://msdn.microsoft.com/en-us/magazine/jj991977.aspx[Async/Await - Best Practices in Asynchronous Programming]