How to safely mix sync and async code?

Try to start from the bottom up, or you run into deadlocks (

Console apps behave differently from web and UI apps as far as how they handle deadlocks if they're NOT properly handled. If you're using MVC, use an async task ActionResult and wrap specific synchronous calls on Task.Run(() => SYNCCODE) using async and await. Similar process with UI code, using async/await upon event methods (such as Click event handlers).

I typically wrap my sync calls with async versions and handle them as tasks. If those sync methods can utilize Async versions of .NET methods, I try to go "deeper in" where possible.


I strongly encourge you not to do this

First, read Should I expose synchronous wrappers for asynchronous methods? and Should I expose asynchronous wrappers for synchronous methods? by Stephan Toub.

The main reasons I wouldn't do this:

  1. Sync over Async - As you said, deadlocks. Higher or lower down the call chain, using Result or Wait on async maybe risky business. It really depends on which platform you run (ASP.NET, UI, Console) as each one behaves a bit differently (Even when using ConfigureAwait(false))

  2. Async over Sync - Scalability. Once I see an async endpoint, I assume it is pure async, which for me, as the consumer of the API means there isn't any Thread spinning "behind my back". If your users assume the same, finding out that for every call to an async method a Thread Pool thread is used can drastically hurt performance when trying to scale out. If the users want to wrap a sync method with a Task.Run, leave it up to them to make that call and make their on judgement on how this will affect their application