## 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.

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

    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

    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

- Async/Await - Best Practices in Asynchronous Programming