How so? Practically everything that should be async, can be, and in a straightforward fashion. Biggest pain point was the reliance on generated code that complicated debugging and potentially reduced performance, but this is being addressed in upcoming .NET releases.
It just doesnt generally work how I would expect it to work until you learn the details of how to make it work how you expect. Especially as you get into RX it gets really confusing about which execution context you should be on. And execution contexts in mobile land are pretty convoluted to setup IMO.
So yes "async" is easy, but "multithreaded/parallel" is a lot more error prone and explicit.
EDIT: I should also note I havent been in the space for a few years so Im not fully current on how it looks today
Async carries its own ExecutionContext that crosses threads.
Multi-threaded/parallel is a LOT easier now with the Task Parallel Library (TPL, https://learn.microsoft.com/en-us/dotnet/standard/parallel-p...) and System.Threading.Channels. Channels in particular are nice because it can fan out and then back in to one aggregator, removing the need for self managing synchronization primitives.
I usually default to channels first, TPL when I want threads.