Asynchronity doesn't say anything about a thread. Its about the presence of some kind of callbacks that will be processed inside the "statemachine" (not quite right, but you can think of it as events). Asynchrony does not create threads or allocate system resources. You can run as many asynchronous methods as you want.
Streams really make sense on your system, and you have a hughe, but a limited number that you can have right away.
Io operations are mainly related to other controllers (HDD, NIC, ...) What now happens if you create a thread is that your application thread, which has nothing to do, is waiting for the controllers to finish working. In async, like Karsten and Jeffrey already mentioned that you just get some kind of callback mechanism, so your thread continues to do other work, methods, etc.
Also keep in mind that each thread is worth the resources (RAM, Performance, Handles Collection Garbage Collection is degrading, ...) and may even be in exceptions (OutOfMemoryException ...)
So, when to use Threads? Absolutely only if you really need it. If there is an async api, use it if you have no really important reason not to use it. In the past days, asynchronous api was very painful, so many people used threads when they needed just asynchrony.
For example, node.js generally refuses to use mulptile thread!
This is especially important if you are processing multiple requests, for example, in services / websites where there is always work. There is also a short broadcast with Jeffrey Richter about this that helped me understand
See also the MSDN PS article: How side-effect source code with asynchronous and wait is generally more readable.