Short question:
Why did .Net Framework add a lot of *Async versions of method instead of developers just using Task.Run
to run synchron
Marking the methods async means that we can use the await keyword to basically schedule the heavy processing on another thread and free the UI thread until the processing is finished.
That's not at all how async
works. See my async intro.
You may say that the *Async methods use some special magic (like handling external signals) that make them more efficient than their synchronous counterparts. The thing is that I don't see this beeing the case.
In pure asynchronous code, there is no thread (as I explain on my blog). In fact, at the device driver level, all (non-trivial) I/O is asynchronous. It is the synchronous APIs (at the OS level) that are an abstraction layer over the natural, asynchronous APIs.
Let's look at the Stream.ReadAsync for example.
Stream
is an unusual case. As a base class, it has to prevent breaking changes as much as possible. So, when they added the virtual ReadAsync
method, they had to add a default implementation. This implementation has to use a non-ideal implementation (Task.Run
), which is unfortunate. In an ideal world, ReadAsync
would be (or call) an abstract asynchronous implementation, but that would break every existing implementation of Stream
.
For a more proper example, compare the difference between WebClient
and HttpClient
.