Потому что в винформах свой synchronization context, а в консоли - стандартный.
Почему в ConsoleApp после await меняется поток
Вообще-то смена потока не гарантируется ;)
Я знаю, что объекты интерфейса можно менять в единственном GUI-потоке.
Вот ради этого контекст синхронизации и существует.
CLR не нужно ничего понимать - ему заранее сообщается, что нужно использовать контекст синхронизации.
Где именно это в недрах винформ происходит - не подскажу (надеюсь, меня дополнят)
Если этого не сделать - используется стандартное поведение при котором разрешено менять потоки.