Дедлок из-за .Result
Вопрос
В обработчике кнопки WinForms вызывают var s = GetAsync().Result;, а внутри GetAsync есть await httpClient.GetStringAsync(url); без ConfigureAwait. Что произойдёт?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
- Всё сработает, просто UI подвиснет на время HTTP-запроса
.ResultброситInvalidOperationExceptionв UI-потоке- Дедлок: UI-поток ждёт
.Result, а продолжение ждёт UI-потокправильный ответ - Продолжение выполнится на пуле потоков, и всё завершится нормально
Разбор
await захватил SynchronizationContext UI и хочет продолжить в UI-потоке. А UI-поток заблокирован на .Result и ждёт завершения задачи, которая не может завершиться без него. Это взаимная блокировка. В ASP.NET Core контекста синхронизации нет, поэтому там такой дедлок не возникает, но блокировка всё равно тратит поток пула. Лечение: асинхронность до конца (await вместо .Result), а в библиотеках ConfigureAwait(false).
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.