121

In .Net 4.5 Microsoft has added the new Async/Await feature to simplify asynchronous coding. However, I wonder

  1. Can Async/Await completely replace the old way of using Threads?
  2. Is Async/Await capable of doing whatever a Thread can do asynchronously?
  3. Can Async/Await only be used with some methods like WebClient.DownloadStringAsync or can I convert any synchronous method to make it use Async/Await and not to block the main thread?
Gary Barrett
  • 1,764
  • 5
  • 21
  • 33
Roman Ratskey
  • 5,101
  • 8
  • 44
  • 67
  • 2
    Threads and Async/Await are unrelated features. You can combine them, but you don't have to. – dtb Mar 01 '13 at 01:30
  • 2
    I thought that Async/Await is doing the same thing that `new Thread(() => {Some Work}).Start();` is doing ?! isn't it ? – Roman Ratskey Mar 01 '13 at 01:34
  • 2
    Nope. Your assumption is not correct. You might be thinking of [Task.Run](http://msdn.microsoft.com/en-us/library/hh195051.aspx) (TPL), which often is combined with Async/Await, but is also unrelated and does not have to be used with it. – dtb Mar 01 '13 at 01:37
  • 4
    @dtb: So when to use Async/Await and when to use Threads ?. I am really confused about the difference between Task.Run, Thread.Start, Async/Await. If you could provide me with a good explanation that makes me understand the differences between them i would be very thankfull – Roman Ratskey Mar 01 '13 at 01:43
  • 2
    Async/await doesn't create or in any other way use threads. – wRAR Mar 01 '13 at 02:11
  • 1
    @RomanRatskey A thread is "time on the CPU". A `Task` is something that produces a result at some point in the future, possibly (but usually not) using a thread. In old school asynchronous programming we used threads to do multiple pieces of work at the same time (by wasting time on the CPU). With `Task` you can avoid using CPU time for things that do not use CPU time (like waiting for a `WebClient.DownloadStringAsync`.). – Aron Aug 23 '16 at 02:12
  • Link suggested by [user](https://stackoverflow.com/users/3085342/user3085342) - https://blogs.msdn.microsoft.com/benwilli/2015/09/10/tasks-are-still-not-threads-and-async-is-not-parallel/ – Alexei Levenkov Oct 03 '17 at 17:30
  • [The official statement on this.](https://msdn.microsoft.com/library/hh191443(vs.110).aspx) Though you should understand the differences between threads and asynchronous programming before blindly replacing one things with others. – wRAR Mar 01 '13 at 02:12

2 Answers2

87

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.

WEFX
  • 8,298
  • 8
  • 66
  • 102
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 5
    In modern C# aspect what's the best approach to achieve Async-Callbacks on external APIs? – bonCodigo May 19 '14 at 05:13
  • 6
    Covered in the last paragraph, use a Task. – Hans Passant Apr 26 '15 at 12:24
  • I would expect something that a thread can do that can't be done via async programming as an example. – Saeed Neamati Jan 24 '16 at 03:59
  • 2
    Could you expand on "A thread can do many more useful things."? It would be useful to understand the features threads provide that `async` is unsuitable for. – Benjohn Nov 08 '16 at 08:49
  • There isn't much to say, threading was a solution to the multicore revolution of the mid 2000s. Running code on more than one processor core can get the job done a lot quicker. Specifically not what async is meant to do. – Hans Passant Nov 08 '16 at 09:51
  • 2
    Hi Hans, just noticed this excellent answer from you, you should clarify the last paragraph, it doesn't need to be a task though, it can be anything for which there exists an GetAwaiter instance or extension method that returns an object that implements INotifyCompletion and have a IsCompleted bool property and a GetResult method returning the result of awaiting whatever. Could be too technical for this question though, just thought I'd mention it. – Lasse V. Karlsen Nov 08 '16 at 09:54
  • 1
    Worth mentioning `await Task.Run` for cpu-bound work. If I understand correctly, that sometimes accomplishes what one would otherwise create a thread, or a background worker, to do. – ToolmakerSteve Jun 27 '18 at 05:26
  • Does this mean that the code on an async method runs essentially like an interrupt routine, which can fire off at any time? Or does it wait for the main thread to be be dormant? Are there any locking/concurrency guarantees? Does it rely on their being some sort of message pump? – Tuntable Feb 19 '21 at 08:40
  • Does Task.Run start a new thread automatically? – variable Jul 24 '21 at 13:05
  • @variable `Task.Run()` will use an existing thread from the thread pool. – David Klempfner Oct 26 '21 at 10:16
5

I think about it this way (and I think Microsoft does too if you look at https://learn.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.

xflowXen
  • 396
  • 4
  • 8