Read() Took 162ms and totalRead: 162835040
ReadAsync() Took 15597ms and totalRead: 162835040

The ReadAsync() is about 100 times slower. Am I missing anything? The only thing I can think of is the overhead to create and destroy task using ReadAsync(), but is the overhead that much?

UPDATE:

I've changed the above code to reflect the suggestion by @Cory. There is a slight improvement:

Read() Took 142ms and totalRead: 162835040
ReadAsync() Took 12288ms and totalRead: 162835040

When I increase the read block size to 1MB as suggested by @Alexandru, the results are much more acceptable:

Read() Took 32ms and totalRead: 162835040
ReadAsync() Took 76ms and totalRead: 162835040

So, it hinted to me that it is indeed the overhead of the number of tasks which causes the slowness. But, if the creation and destroy of task only takes merely 100µs, things still don't really adds up for the slowness with a small block size.

Stick with big buffers if you're doing async and make sure to turn on async mode in the FileStream constructor, and you should be okay. Async methods that you await like this will trap in and out of the current thread (mind you the current thread is the UI thread in your case, which can be lagged by any other async method facilitating the same in and out thread trapping) and so there will be some overhead involved in this process if you have a large number of calls (imagine calling a new thread constructor and awaiting for it to finish about 100K times, and especially if you're dealing with a UI app where you need to wait for the UI thread to be free in order to trap back into it once the async function completes). So, to reduce these calls, we simply read in larger increments of data and focus the application on reading more data at a time by increasing the buffer size. Make sure to test this code in Release mode so all of the compiler optimizations are available to us and also such that the debugger does not slow us down: