The solution to deadlocking is using async all the way down - i.e. don't use .Result.
you can also tell C# not to resume on the same context after an async call by using .ConfigureAwait(false) on the tasks, thus preventing two locks on a context, and the deadlock.<p>The author states two threads accessing a single resource is a race-condition, but that's only true when the threads are competing for that resource - in the case outlined in the article, it would be sequential, and only one thread would be accessing the resource at one time. No race condition.<p>I think it's not too wise to think of async/await as a special coroutine which never uses multiple threads, but as an easy way to write synchronous code and have it execute asyncronously. If you need fine control over what threads are used, maybe you're better off controlling it manually.