Task.Run порождает новый поток в большинстве сценариев, насколько я понимаю.
Важно отметить, что просто потому, что вы помечаете метод как асинхронный и используете awaiters, это НЕ (обязательно) означает, что создаются новые потоки, завершения планируются в том же потоке выполнения, из которого они были вызваны в много дел.
Трюк здесь связан с SchedulingContext. Если он установлен для многопоточной квартиры, то вы собираетесь делегировать завершения жизнеспособным потокам в пуле потоков. Если вы находитесь в однопотоковой квартире, как и весь код пользовательского интерфейса WPF и WinForms, то он вернется к вызывающему потоку для завершения, позволяя выполнять работу непосредственно в пользовательском интерфейсе без видимой сортировки потока в коде.