Не вървят паралелно, а се редуват. Когато прогресът е блокиран в един Task, той си запазва състоянието и предава контрола на готов Task. Това е кооперативно multitask-ване, а не реален паралелизъм.
Нишките работят на същия принцип. Обаче има някои разлики.
Първо, просто защото async/await не са нишки на операционната система:
- Task-овете не виждат ID-тата на нишките
- Thread-local storage не сменя автоматично контекста, когато някой Task предаде контрола на друг
Второ, различно държание:
- Async/await използва кооперативно multitask-ване, а Win32 нишките използват pre-emption. Затова е нужно всички блокирани операции да връщат контрола чрез async/await модела. Може да се получи блокиране на цяла нишка с всичките и Task-ове заради извикване на функция, която не е направена да връща контрола върху нишката в случай, че блокира.
- Task-овете няма да се изпълнят паралелно на на многопроцесна система. Тъй като повторното влизане се контролира, това прави доста по-лесно запазването на консистентни структури от данни.
Можеш да получиш едновременно изпълнение с много нишки от операционната система(с цялата им сложнотия и проблеми) ако използваш многонишков synchronization context. Но това,което си цитирал от MSDN, се отнася за случаите с една нишка.