Что такое дедлоки?
Что проверяют
Знаете ли вы не только учебный дедлок на двух блокировках, но и тот, который реально встречается в .NET: смешение синхронного ожидания с асинхронным кодом. Заодно смотрят, чем вы подтверждаете диагноз.
Как отвечать
Общая часть: дедлок это круговое ожидание без вытеснения, лечится единым порядком захвата или ожиданием с таймаутом (попытка входа через Monitor, SemaphoreSlim для асинхронного кода). Внутри lock нельзя выполнить await, и это осознанное ограничение языка.
Специфика платформы: в среде с однопоточным контекстом синхронизации (настольный интерфейс, классический ASP.NET) обращение к Result или Wait блокирует единственный поток контекста, а продолжение после await просится ровно в него.
private void Button_Click(object sender, EventArgs e)
{
var data = LoadAsync().Result; // поток интерфейса встал
}
private async Task<string> LoadAsync()
{
await Task.Delay(100); // продолжение ждёт занятый контекст
return "ok";
}Правило простое: асинхронность насквозь, в библиотеках ConfigureAwait со значением false, синхронного ожидания задач в прикладном коде нет.
Где спотыкаются
Рассказывают только про два объекта и lock. Для этой платформы половина ответа теряется: чаще ломается именно связка блокирующего вызова и await.
Считают ConfigureAwait универсальным лекарством. Он снимает захват контекста внутри библиотеки, но вызывающий код с обращением к Result остаётся неправильным, и на соседней ветке всё повторится.
Переносят вывод на ASP.NET Core без оговорки. Контекста синхронизации там нет, поэтому классического дедлока не будет, зато будет истощение пула потоков под нагрузкой: симптомы другие (таймауты, растущая очередь), корень тот же.