При выполнении await для задачи (самый распространенный сценарий)
в момент, когда await решает приостановить метод, сохраняется контекст.
Это текущий объект SynchronizationContext, если только он не равен
null (в этом случае контекстом является текущий объект TaskScheduler).
Метод возобновляет выполнение в этом сохраненном контексте. Обычно
контекстом является UI-контекст (для UI-потока) или контекст пула
потоков (в большинстве других ситуаций). Если вы пишете приложение
ASP.NET Classic (до Core), то контекстом также может быть контекст
запроса
ASP.NET. В
ASP.NET Core используется контекст пула потоков
вместо специального контекста запроса.
Таким образом, в приведенном коде все синхронные части пытаются
возобновить продолжение в исходном контексте. Если вызвать метод
DoSomethingAsync из UI-потока, каждая из его синхронных частей будет
выполняться в этом UI-потоке, но если вызвать его из потока из пула
потоков, то каждая из синхронных частей будет выполняться в любом
потоке из пула потоков.
Чтобы обойти это поведение по умолчанию, можно выполнить await по
результату метода расширения ConfigureAwait с передачей false в пара-
метре continueOnCapturedContext. Следующий код начинает выполнение
в вызывающем потоке, а после приостановки await он возобновляет вы-
полнение в потоке из пула потоков: