#c_sharp #net #async_await
Коллеги, добрый день. Прошу помощи с 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()?
Ответы
Ответ 1
Смотрите. ConfigureAwait(false) действует напрямую только на await, который ожидает данный Task (точнее, данный tasklike). Это означает, что во внешней функции будет обычным образом захвачен контекст, и выполнение вернётся туда по окончанию await. То, в каком или в каких контекстах пробегает код M1, не играет роли, если M2 бежит в синхронизационном контексте.
Комментариев нет:
Отправить комментарий