Использование ConfigureAwait(false)
в коде приложения обычно не способствует значительному повышению производительности вашего приложения, потому что обычно вы не await
внутри циклов в коде приложения. Например, давайте рассмотрим случай, когда ваше приложение имеет кнопку и асинхронная операция запускается каждый раз, когда пользователь нажимает кнопку, а асинхронная операция включает в себя один await
. Вводя 22 символа .ConfigureAwait(false)
после этого await
, вы уже потеряли сопоставимое время своей жизни, причем время, которое вы можете надеяться сэкономить, от 10 пользователей, которые нажимают эту кнопку каждую минуту, 8 часов в день, в течение 20 лет каждый (~ 35000000 переключений контекста всего = несколько секунд процессорного времени).
И это, прежде чем принимать во внимание время, которое вам нужно подумать о том, можете ли вы безопасно включить эту конфигурацию (в зависимости от того, содержит ли продолжение код, связанный с пользовательским интерфейсом), время, которое вам понадобится, чтобы подтверждать предыдущую оценку каждый раз, когда у вас есть для поддержки / изменения кода и времени, которое вы потеряете на отладку, если ваша оценка окажется неверной.
С другой стороны, если ваш Button_Click
обработчик содержит такой код:
private async void Button_Click(object sender, EventArgs e)
{
var client = new WebClient();
using var stream = await client.OpenReadTaskAsync("someUrl");
var buffer = new byte[1024];
while ((await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
//...
}
}
... тогда непременно потратьте дополнительное время на ConfigureAwait(false)
задачу ReadAsync
. Также рассмотрите возможность рефакторинга кода путем перемещения части чтения потока в отдельный асинхронный метод, чтобы вы могли безопасно получать доступ к элементам пользовательского интерфейса в любом месте внутри обработчика Button_Click
, не отвлекаясь на технические детали, которые не относятся к этому уровню приложения.
person
Theodor Zoulias
schedule
01.07.2020
Are my conclusions correct
- нет. Async - это не потоки. Не существует прямого соответствия междуConfigureAwait
и использованием определенного потока. См., Например, stackoverflow.com/q/46094134/11683. - person GSerg   schedule 01.07.2020Task.Run()
).ConfigureAwait(false)
предполагает возобновление без захвата контекста синхронизации, а не требует этого. Для некоторых контекстов синхронизации (например, того, который используется в приложении Winforms), возобновление в том же контексте означает выполнение в потоке пользовательского интерфейса. Для других контекстов это может не означать этого или вообще не иметь наблюдаемого эффекта. - person GSerg   schedule 01.07.2020ConfigureAwait(false)
для контекстно-зависимого кода, например того, что должно выполняться в потоке пользовательского интерфейса после завершения. Другой пример - доступ к HttpContext в приложении ASP.NET WebForms. Ссылка, которую я опубликовал, указывает на приложение WPF, которое исследует эти вещи, в том числе то, как вы все еще можете заблокироваться при использовании ConfigureAwait (false) с небрежным кодом библиотеки. - person Crowcoder   schedule 01.07.2020