День двести шестнадцатый. #ЗаметкиНаПолях
Многопоточность.
9. Async/await. Продолжение
Асинхронный поток выполнения
Когда поток выполнения достигает выражения await, есть два варианта:
1. Ожидаемая асинхронная операция уже завершена.
В этом случае процесс продолжается, как обычно. Если операция завершилась неудачно и захватила исключение, генерируется исключение. В противном случае возвращается результат (например, извлекается string из Task<string>), и вы переходите к следующей строке программы. Все это делается без какого-либо переключения контекста потока или создания продолжений.
2. Ожидаемая асинхронная операция ещё не завершена.
В этом случае метод асинхронно ожидает завершения операции, а затем продолжает работу в соответствующем контексте. Это асинхронное ожидание означает, что метод не выполняется дальше. К асинхронной операции прикрепляется продолжение, содержащее остаток кода асинхронного метода, а сам метод возвращается. Инфраструктура гарантирует, что продолжение выполняется в нужном потоке: обычно это либо поток из пула (где не имеет значения, какой поток используется), либо поток пользовательского интерфейса. С точки зрения разработчика, можно представить, что метод приостанавливается до тех пор, пока асинхронная операция не завершится. Компилятор гарантирует, что все локальные переменные, используемые в методе, будут иметь те же значения, как это происходит с блоками итераторов при yield return.
Возврат или завершение
Для асинхронных методов есть разница между возвратом из метода и завершением метода. Возврат из асинхронного метода может производиться несколько раз, когда у метода больше нет работы, которую он может сделать на данный момент. А завершиться метод может только один раз.
Замечание: до первого выражения
Продолжение следует…
Источник: Jon Skeet “C# In Depth”. 4th ed – Manning Publications Co, 2019. Глава 5.
Многопоточность.
9. Async/await. Продолжение
Асинхронный поток выполнения
Когда поток выполнения достигает выражения await, есть два варианта:
1. Ожидаемая асинхронная операция уже завершена.
В этом случае процесс продолжается, как обычно. Если операция завершилась неудачно и захватила исключение, генерируется исключение. В противном случае возвращается результат (например, извлекается string из Task<string>), и вы переходите к следующей строке программы. Все это делается без какого-либо переключения контекста потока или создания продолжений.
2. Ожидаемая асинхронная операция ещё не завершена.
В этом случае метод асинхронно ожидает завершения операции, а затем продолжает работу в соответствующем контексте. Это асинхронное ожидание означает, что метод не выполняется дальше. К асинхронной операции прикрепляется продолжение, содержащее остаток кода асинхронного метода, а сам метод возвращается. Инфраструктура гарантирует, что продолжение выполняется в нужном потоке: обычно это либо поток из пула (где не имеет значения, какой поток используется), либо поток пользовательского интерфейса. С точки зрения разработчика, можно представить, что метод приостанавливается до тех пор, пока асинхронная операция не завершится. Компилятор гарантирует, что все локальные переменные, используемые в методе, будут иметь те же значения, как это происходит с блоками итераторов при yield return.
Возврат или завершение
Для асинхронных методов есть разница между возвратом из метода и завершением метода. Возврат из асинхронного метода может производиться несколько раз, когда у метода больше нет работы, которую он может сделать на данный момент. А завершиться метод может только один раз.
Замечание: до первого выражения
await
, метод выполняется полностью синхронно. Вызов асинхронного метода не похож на запуск новой задачи в отдельном потоке, и вы должны убедиться, что всегда пишете асинхронные методы так, чтобы они быстро возвращались. Конечно, это зависит от контекста, в котором вы пишете код, но, как правило, следует избегать выполнения длительной работы в асинхронном методе. Выделите её в другой метод, для которого создайте отдельную задачу.Продолжение следует…
Источник: Jon Skeet “C# In Depth”. 4th ed – Manning Publications Co, 2019. Глава 5.