Правильно ли я, что async / await не имеет ничего общего с параллелизмом / параллелизмом и является не чем иным, как реализацией CPS?
Что ж, async
/ await
- это переписывание с использованием CPS, так что ваше основное понимание правильное.
Что касается «параллелизма» и «параллелизма», я бы сказал, что он действительно обеспечивает параллелизм; вы можете запускать несколько async
операций, которые все находятся «в полете» одновременно. Это легко сделать с помощью Task.WhenAll
и Task.WhenAny
.
Кроме того, хотя async
сам по себе не подразумевает "многопоточность", Task.Run
действительно обеспечивает легкую async
-совместимую многопоточность.
А реальная потоковая передача выполняется экземпляром SynchronizationContext, который await передает / восстанавливает?
Подумайте об этом так: продолжение, созданное перезаписью CPS, должно запускаться где-то. Захваченный «асинхронный контекст» можно использовать для планирования продолжения.
Боковое примечание: захваченный контекст на самом деле SynchronizationContext.Current
, если он не равен нулю, и в этом случае захваченный контекст - это TaskScheduler.Current
.
Еще одно важное замечание: захват и восстановление контекста фактически зависит от объекта "awaiter". Итак, по умолчанию, если вы await
a Task
(или любой другой встроенный объект ожидания), контекст будет захвачен и восстановлен. Но если вы await
результат ConfigureAwait(false)
, то контекст не улавливается. Точно так же, если вы await
ваш собственный ожидаемый объект, он не будет захватывать контекст (если вы не запрограммируете его для этого).
Однако есть ли какие-либо гарантии того, что контекстная информация потока сохраняется? Я имею в виду Name, CurrentPrincipal, CurrentCulture, CurrentUICulture и т. Д.
SynchronizationContext
отличается от ExecutionContext
. Упрощенный ответ состоит в том, что ExecutionContext
всегда "течет", поэтому CurrentPrincipal
течет (если нет, это может быть проблемой безопасности, поэтому API-интерфейсы, не использующие поток ExecutionContext
, всегда заканчиваются на Unsafe
).
В приложениях пользовательского интерфейса культура не передается, но по умолчанию она одинакова для всех потоков. Name
определенно не будет выполняться, если вы не возобновите работу в том же потоке (например, используя пользовательский интерфейс SynchronizationContext
).
Для дальнейшего чтения я рекомендую начать с моего собственного async
/ await
учебника, а затем официальный async
/ await
FAQ. Затем взгляните на сообщение в блоге Стивена Туба о ExecutionContext
vs. SynchronizationContext
.
Вам также может быть полезна моя SynchronizationContext
статья.
person
Stephen Cleary
schedule
17.09.2012
SynchronizationContext
не гарантирует, что продолжение будет выполнено в том же потоке. Некоторые контексты для этого (WPF, Winforms), но другие нет (ASP.NET). - person svick   schedule 17.09.2012