ConfigureAwait в .NET 8. Окончание
Начало
None и ContinueOnCapturedContext
Эти опции очевидны, с небольшим замечанием.
ContinueOnCapturedContext — то же самое, что true, т.е. ожидание захватит контекст и возобновит выполнение асинхронного метода в этом контексте.
None — то же самое, что false, т.е. ожидание не будет захватывать контекст.
Замечание. По умолчанию контекст НЕ захватывается. Если явно не добавить ContinueOnCapturedContext, контекст не будет захвачен.
Поведение по умолчанию не изменилось: отсутствие ConfigureAwait аналогично true или ContinueOnCapturedContext. Но при использовании других опций ConfigureAwaitOptions, для захвата контекста нужно будет добавлять флаг ContinueOnCapturedContext (см. ниже).
SuppressThrowing
Этот флаг подавляет исключения, которые в противном случае могли бы возникнуть при ожидании задачи. В нормальных условиях await отслеживает исключения в задачах, повторно выбрасывая их в момент ожидания. Обычно это именно то поведение, которое вам нужно, но бывают ситуации, когда вы просто хотите дождаться завершения задачи и вас не волнует, завершится ли она успешно или с исключением. SuppressThrowing позволяет дождаться завершения задачи, не наблюдая за её результатом.
Это скорее всего будет полезно при отмене задач. Иногда нужно вызвать отмену задачи, дождаться её, а затем выполнить другую задачу вместо отменённой. Тогда отменяемую задачу можно ожидать с SuppressThrowing, и метод продолжит работу после завершения задачи, независимо от того, была ли она успешной, отменённой или вызвала исключение.
Замечание: эта семантика не работает для Task<T>, поскольку в этом случае ожидание должно возвращать значение типа T. Неясно, какое значение будет уместно вернуть в случае игнорируемого исключения, поэтому текущее поведение заключается в выдаче исключения ArgumentOutOfRangeException во время выполнения. Было добавлено новое предупреждение:
CA2261: The ConfigureAwaitOptions.SuppressThrowing is only supported with the non-generic Task (ConfigureAwaitOptions.SuppressThrowing поддерживается только с необобщённым Task).
Это предупреждение лучше сделать ошибкой, поскольку во время выполнения оно всегда будет давать сбой.
ForceYielding
ForceYielding – флаг, который может быть полезен в очень редких случаях, но в этих случаях он будет очень удобен. Он похож на Task.Yield. Yield возвращает специальную ожидаемую задачу, которая всегда утверждает, что она не завершена, но немедленно планирует продолжение. Обычно await проверяет, завершена ли ожидаемая задача и, если да, продолжает синхронно. ForceYielding предотвращает такое синхронное поведение, заставляя ожидание вести себя асинхронно. Это может быть полезно, например, при модульном тестировании.
Обратите внимание, что сам по себе флаг ForceYielding также подразумевает отказ от продолжения работы с захваченным контекстом, поэтому это то же самое, что сказать «запланировать остальную часть этого метода для выполнения в пуле потоков» или «переключиться на поток из пула потоков».
Task.Yield возобновит работу в захваченном контексте, поэтому это не то же самое, что ForceYielding. Task.Yield аналогично комбинации флагов
ForceYielding | ContinueOnCapturedContext.Конечно, реальная ценность ForceYielding в том, что его можно применить к любой задаче. Раньше приходилось либо добавлять отдельный
await Task.Yield(); либо создавать собственный ожидаемый объект. Теперь в этом больше нет необходимости, поскольку ForceYielding можно применять к любой задаче. Источник: https://blog.stephencleary.com/2023/11/configureawait-in-net-8.html