Async/Await vs Threads
Solution 1:
can it completely replace the old way of using Threads ?
No. A thread can do many more useful things. Await is specifically designed to deal with something taking time, most typically an I/O request. Which traditionally was done with a callback when the I/O request was complete. Writing code that relies on these callbacks is quite difficult, await greatly simplifies it.
capable of doing what ever a Thread can do asynchronously ?
Roughly. Await just takes care of dealing with the delay, it doesn't otherwise do anything that a thread does. The await expression, what's at the right of the await keyword, is what gets the job done. Ideally it doesn't use a thread at all, it posts a driver request and once the driver completes the data transfer it generates a completion notification callback. Networking is by far the most common usage, latencies of hundreds of milliseconds are common and an inevitable side-effect of services moving from the desktop or a LAN into "the cloud". Using such services synchronously would make a UI quite unresponsive.
only can be used with some methods like WebClient.DownloadStringAsync
No. You can use it with any method that returns a Task. The XxxxAsync() methods are just precooked ones in the .NET framework for common operations that take time. Like downloading data from a web server.
Solution 2:
The official statement on this. Though you should understand the differences between threads and asynchronous programming before blindly replacing one things with others.
Solution 3:
I think about it this way (and I think Microsoft does too if you look at https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2012/hh191443(v=vs.110)#threads)
Async/await is a quick way to run some code on the main application thread with the advantage that the code can suspend itself when it has no work to do and return focus to the main thread, "wake up" on the main thread when there is a result to be obtained and then pass processing back to - you guessed it - the main thread. Think of it like an event based GOTO statement in Basic that can pass control back and forth to a specific line of execution.
In contrast a thread is a separate stream of execution that can run with its own variables etc. where - given sufficient hardware - execution occurs in parallel to the main thread.
If you have a GUI application that is going to download a single file and then do something with that file when its downloaded - I'd implement that using an async/await method.
However if your GUI needs to download 5000 files - I'd create a file download thread to handle that since the main GUI thread may freeze while execution is transferred to handle downloading the files.