Работали ли вы с синхронным кодом в C#
Что проверяют
Вопрос звучит про синхронный код, а проверяют границу между синхронностью и асинхронностью: понимаете ли вы, что async не ускоряет операцию, и знаете ли, чем кончается блокирующее ожидание асинхронного метода.
Как отвечать
Синхронный вызов удерживает поток до конца работы. Для вычислительной задачи это нормально и правильно: async там ничего не даст, ускорение приходит от распараллеливания через Parallel.For или задачи на пуле. Для ввода-вывода блокирующий вызов держит поток впустую, и на сервере это упирается в исчерпание пула и рост очереди запросов.
Главное правило формулируется коротко: не смешивать два мира.
var ok = await client.GetStringAsync(url);
var bad = client.GetStringAsync(url).Result; // так нельзя.Result, .Wait() и GetAwaiter().GetResult() поверх асинхронного метода дают взаимную блокировку там, где есть контекст синхронизации: классический веб-стек, оконные приложения. В современном серверном стеке контекста нет и дедлока не будет, но поток всё равно простаивает.
Если библиотека предлагает только синхронный интерфейс, вызов уводят на пул на границе кода, а не переписывают всё вокруг под видимость асинхронности.
Где спотыкаются
Говорят, что асинхронный код быстрее. Одну операцию он не ускоряет ни на йоту, он освобождает поток на время ожидания, и выигрыш виден только под нагрузкой, когда потоков перестаёт хватать.
Пишут async void не в обработчике события. Исключение из такого метода не ловится внешним try и уносит процесс целиком. Возвращать надо Task, тогда ошибку можно дождаться и обработать.
Оборачивают синхронную работу в задачу внутри веб-запроса и называют это асинхронностью. Поток переехал из одного пула в другой, суммарное потребление не изменилось, а стоимость переключений выросла.