Коллеги, добрый день. Прошу помощи с ConfigureAwait().
Мои знания на таком уровне: это метод, который указывает среде выполнения, что при возвращении из асинхронного метода (запущенного в другом потоке) не нужно пользоваться контекстом синхронизации. Т.е. не ждать пока освободится поток, в котором началось выполнение кода (до await), а продолжать выполнение кода (который после await) в том же потоке, в каком выполнялся сам асинхронный таск (сам await).
Это повышает производительность, однако стоит использовать с осторожностью в задачах где присутствуют UI потоки (WPF, ASP.NET). Поправьте пожалуйста, если я не прав.
И дальше возникает второй вопрос. Допустим у меня есть такая цепочка асинхронных вызовов:
public async Task M1()
{
return await M2();
}
public async Task M2()
{
return await M3();
}
public async Task M3()
{
return await
dbContext.Users
.ToListAsync()
.ConfigureAwait(false);
}
В методе M3() происходит асинхронное ожидание. EF создает новый поток и читает из БД, мы ждем. Все ок.
А что происходит в M2()? Создается ли новый поток для выполнения таска await M3(). Аналогичный вопрос для метода M1(). Стоит ли в этих await-ах использовать ConfigureAwait(false), либо достаточно того, что мы использовали этот метод в M3()?
Ответ
Смотрите.
ConfigureAwait(false) действует напрямую только на await, который ожидает данный Task (точнее, данный tasklike). Это означает, что во внешней функции будет обычным образом захвачен контекст, и выполнение вернётся туда по окончанию await. То, в каком или в каких контекстах пробегает код M1, не играет роли, если M2 бежит в синхронизационном контексте.
Комментариев нет:
Отправить комментарий