In this interview, Eric Lippert compared async await with a cook making breakfast. It helped me a lot to understand the benefits of async-await. Search somewhere in the middle for 'async-await'
Suppose a cook has to make breakfast. He has to toast some bread and boil some eggs, maybe make some tea as well?
Method 1: Synchronous. Performed by one thread. You start toasting the bread. Wait until the bread is toasted. Remove the bread. Start boiling water, wait until the water boils and insert your egg. Wait until the egg is ready and remove the egg. Start boiling water for the tea. Wait until the water is boiled and make the tea.
Youl see all the waits. while the thread is waiting it could do other things.
Method 2: Async-await, still one thread You start toasting the bread. While the bread is being toasted you start boiling water for the eggs and also for the tea. Then you start waiting. When any of the three tasks is finished you do the second part of the task, depending on which task finished first. So if the water for the eggs boils first, you cook the eggs, and again wait for any of the tasks to finish.
In this description only one person (you) is doing all the stuff. Only one thread is involved. The nice thing is, that because there is only one thread doing the stuff the code looks quite synchronous to the reader and there is not much need to make your variables thread safe.
It's easy to see that this way your breakfast will be ready in shorter time (and your bread will still be warm!). In computer life these things will happen when your thread has to wait for another process to finish, like writing a file to a disk, getting information from a database or from the internet. Those are typically the kind of functions where'll see an async version of the function: Write
and WriteAsync
, Read
and ReadAsync
.
Addition: after some remarks from other users elsewhere, and some testing, I found that in fact it can be any thread who continues your work after the await. This other thread has the same 'context', and thus can act as if it was the original thread.
Method 3: Hire cooks to toast the bread and boil the eggs while you make the tea: Real asynchronous. Several threads This is the most expensive option, because it involves creating separate threads. In the example of making breakfast, this will probably not speed up the process very much, because relatively large times of the process you are not doing anything anyway. But if for instance you also need to slice tomatoes, it might be handy to let a cook (separate thread) do this while you do the other stuff using async-await. Of course, one of the awaits you do is await for the cook to finish his slicing.
Another article that explains a lot, is Async and Await written by the ever so helpful Stephen Cleary.