One thing that still surprises me is that C# doesn't have something like a generic async: IE, write one method, and the compiler creates both sync and async versions.
(Now, you might be thinking, "no, that won't work because of XYZ corner case," and I would say that: 1: If those corner cases apply, then you should be writing both versions of a method; and 2: For the vast majority of APIs that need to create both sync and async methods, the only difference between the methods is dropping "async ... Async" from within the implementation.)
Or, alternatively, one thing that surprises me about C# is that the JIT can't support calling "async from sync:" IE, it can't, at the lowest levels, swap in a blocking call. (So you don't have to write separate sync and async APIs.)