The two languages have two different async abstractions which at their core aren't compatible in general. When that happens in software, one of several possible options will happen. The thing Microsoft chose here is to give an API that looks like it's compatible but which is subtly broken for a nontrivial fraction of code (other common choices include rejecting any level of compatibility, providing more complicated APIs allowing the user to handle the multi-language nuances, or providing an incomplete API which works as expected).
Much like how when one proposes a perpetual motion machine you know there must be a bug in the math somewhere, when somebody proposes an interop between two incompatible data structures there must also be a drawback. Pick literally any feature of the language other than sequentially executing code (exceptions and threads are usually great ways for languages and specs to fall apart), and you'll likely find places where the interop struggles. A few that come to mind:
- That solution is only one direction. Interoperability needs to go both ways.
- The exception interface between the two constructs is sufficiently poorly defined that I'd call it a footgun, and code that won't wake you up at night usually has to do extra work.
- Performance in that kind of wrapping is a nightmare, both from the overhead of additional runtime layers, and, more importantly, because the last time I checked it was basically "sync over async" in a way that made the type system happy.
- Going back to the exception thing, cancellation tokens are especially poorly handled in that interop one-liner.
- They still haven't fixed blunders like ConfigureAwait(false), and the interop code absolutely has to care about that sort of thing in applicable contexts (the worst offenders being any sort of "main thread owns everything" code like current popular GUI paradigms).