Подтвердить что ты не робот

Почему ConfigureAwait (false) не является параметром по умолчанию?

Как вы знаете, это хорошая идея называть Task.ConfigureAwait(false), когда вы ожидаете задачи в коде, который не требует захвата контекста синхронизации, поскольку он может вызывают взаимоблокировки в противном случае.

Хорошо, как часто вам нужно фиксировать контекст синхронизации? Я очень редко использую эту практику. В большинстве случаев я работаю с "библиотечным" кодом, который в значительной степени заставляет меня использовать Task.ConfigureAwait(false) все время.

Итак, мой вопрос довольно прост: почему Task.ConfigureAwait(false) не является параметром по умолчанию для задачи? Не было бы намного лучше заставить "высокоуровневый" код использовать Task.ConfigureAwait(true)? Есть ли историческая причина для этого, или я чего-то не хватает?

4b9b3361

Ответ 1

Просто потому, что для типичного варианта использования вашего требуется ConfigureAwait (false), это не значит, что это "правильный" или наиболее используемый вариант.

Одна из задач async/await предназначена для написания гибких графических программ. В таких случаях возврат к потоку пользовательского интерфейса после разгрузки какой-либо работы в задачу имеет решающее значение, поскольку обновления пользовательского интерфейса могут произойти только из основного потока на большинстве платформ Windows GUI. Async/await помогает разработчикам графического интерфейса делать правильные вещи.

Это не единственный пример, когда опция по умолчанию имеет смысл. Я могу только догадываться, но я подозреваю, что решение для ConfigureAwait по умолчанию основано на том, что async работает с минимальным трением, насколько это возможно, для случаев использования, которые Microsoft ожидает, что он будет использоваться для большинства. Не каждый пишет фреймворки.

Ответ 2

Большая часть кода, который работает с .ConfigureAwait(false), также работает, хотя и подмножественно, с .ConfigureAwait(true). Да, не весь код, но еще самый. Текущее значение по умолчанию позволяет работать с самым высоким процентом кода без использования настроек, которые, к сожалению, типичный программист не понимает.

Другое значение по умолчанию просто приведет к тысячам вопросов о том, почему код не работает, а еще хуже, тысячи ответов в форме "Microsoft отстой", они заставляют вас писать Control.CheckForIllegalCrossThreadCalls = false; в каждой программе. Почему isn ' t что по умолчанию? " вместо фактического добавления соответствующих вызовов .ConfigureAwait(true).

Ответ 3

Посмотрите на второе примерное решение по этой ссылке:

public async void Button1_Click(...)
{
  var json = await GetJsonAsync(...);
  textBox1.Text = json;
}

public class MyController : ApiController
{
  public async Task<string> Get()
  {
    var json = await GetJsonAsync(...);
    return json.ToString();
  }
}

Если по умолчанию было ConfigureAwait(false), оператор textBox1.Text = json; выполнял бы в потоке пула случайных потоков вместо потока пользовательского интерфейса.

Оба фрагмента выглядят как код, который может разумно написать, и по умолчанию один из них должен быть сломан. Так как взаимоблокировки намного менее опасны и проще обнаружить, чем небезопасные обращения, выбор ConfigureAwait(true) по умолчанию является более консервативным выбором.