Выбор ответа Senior async/await и Task обновлено
TaskCompletionSource и синхронные продолжения
Вопрос
Почему new TaskCompletionSource<T>() часто создают с флагом TaskCreationOptions.RunContinuationsAsynchronously?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: Иначе продолжения могут выполниться синхронно внутри SetResult. По умолчанию SetResult может сразу выполнить продолжения ожидающих прямо в своём стеке вызовов.
Варианты ответа
- Без флага задача никогда не завершится после вызова
SetResult - Флаг делает
SetResultпотокобезопасным при вызове из разных потоков - Иначе продолжения могут выполниться синхронно внутри
SetResultправильный ответ - Флаг запрещает ожидать задачу дважды и тем защищает от гонок
Разбор
По умолчанию SetResult может сразу выполнить продолжения ожидающих прямо в своём стеке вызовов. Если вызывающий держит lock или это поток ввода-вывода, чужой код неожиданно выполнится внутри, что ведёт к дедлокам и подвисаниям. Флаг заставляет планировать продолжения в пул. Задача завершится и без флага, SetResult и TrySetResult и так безопасны для вызова из разных потоков, а многократное ожидание Task разрешено.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.