One at a time
Code is executed to achieve a purpose. Usually it's run as a series of steps, eventually leading to a final result. Each of the steps take some time to execute, and running them synchronously, one after the other, can take a significant amount of time.
Say you're a Doctor of Evil - a Dr. Evil if you will. And you want to run a successful criminal enterprise to take over the world; maybe you're looking to make One Million Dollars... Would it be the most effective way to run all of your plans one after the other?
Running an Evil Empire
The first thing you'll need, as an evil mastermind, is of course an Evil Lair.
-
Task.Delay(x)gives a logical delay ofxmilliseconds without blocking the current thread
public static void BuildAnEvilLair()
{
await Task.Delay(5000);
Console.WriteLine("Evil Lair Built!");
}
After you build your lair, you're going to need to hire some henchman.
public static void HireSomeHenchman()
{
await Task.Delay(2000);
Console.WriteLine("Henchman Hired!");
}
And of course, you'll need to create a mini clone of yourself.
public static void MakeMiniClone()
{
await Task.Delay(3000);
Console.WriteLine("Mini Clone Created!");
}
Once all of this is in place, you can start working on your Super Evil Plan!
public static void SuperEvilPlan()
{
await Task.Delay(4000);
Console.WriteLine("Super Evil Plan Completed!");
}
And let's not forget threatening world leaders with your Super Evil Plan and ransoming One Million Dollars.
public static int MakeOneMillionDollars()
{
await Task.Delay(2000);
Console.WriteLine("Million Dollars Made!");
return 1000000;
}
Finally, when everything has been completed, we can achieve World Domination.
public static void WorldDomination()
{
await Task.Delay(6000);
Console.WriteLine("World Domination Achieved!");
}
Putting our plan together,
BuildAnEvilLair();
HireSomeHenchman();
MakeMiniClone();
SuperEvilPlan();
var money = MakeOneMillionDollars();
WorldDomination();
which takes 22 000ms (or 22 seconds) synchronously.
All at once
Many of the steps in such a synchronous plan can be executed in parallel, asynchronously. So how is this done?
First, all the methods will be made asynchronous with the async descriptor, and their executing code will be awaited.
Awaiting asynchronous code, the awaiting code is processed asynchronously, and the code following the await is added as a continuation to the await. The continuation will be run after the code being awaited has run its duration and been successfully executed.
public static async Task BuildAnEvilLair()
{
await Task.Delay(5000);
Console.WriteLine("Evil Lair Built!");
}
public static async Task HireSomeHenchman()
{
await Task.Delay(2000);
Console.WriteLine("Henchman Hired!");
}
public static async Task MakeMiniClone()
{
await Task.Delay(3000);
Console.WriteLine("Mini Clone Created!");
}
public static async Task SuperEvilPlan()
{
await Task.Delay(4000);
Console.WriteLine("Super Evil Plan Completed!");
}
public static async Task<int> MakeOneMillionDollars()
{
await Task.Delay(2000);
Console.WriteLine("Million Dollars Made!");
return 1000000;
}
public static async Task WorldDomination()
{
await Task.Delay(6000);
Console.WriteLine("World Domination Achieved!");
}
With output
Million Dollars Made!
Super Evil Plan Completed!
Mini Clone Created!
Evil Lair Built!
Henchman Hired!
World Domination Achieved!
Clearly this is a mess. Everything is happening at once. It's really fast - only dependent on the slowest method (6000ms). It's obvious that some calls are dependent on others. Now we need to synchronise them with each other.
Effectively Asynchronous
So, as an Evil Mastermind, which tasks would you run and in which order?
First, we need an evil lair. After that we can hire some henchman and create a mini clone of ourselves. Then we can come up with a Super Evil Plan, after which we can make One Million Dollars and achieve World Domination.
Changing the executing code we can achieve this by using the right mix of await and Task.WaitAll. Task.WaitAll fires off all the tasks asynchronously and finishes awaiting those tasks once all the tasks have completed - so the Task.WaitAll takes as long as the longest task it's awaiting.
Let's try this again.
// First we need an Evil Lair
await BuildAnEvilLair();
// Next, hire Henchman and create a Clone (asynchronously)
Task.WaitAll(HireSomeHenchman(), MakeMiniClone());
// Now, come up with the evil plan
await SuperEvilPlan();
// And finally, make One Million Dollars (and achieve World Domination)
Task.WaitAll(MakeOneMillionDollars(), WorldDomination());
With output,
Evil Lair Built!
Henchman Hired!
Mini Clone Created!
Super Evil Plan Completed!
Million Dollars Made!
World Domination Achieved!
Taking a cool 18 000ms (18 seconds). 4 seconds less than the synchronous implementation.
So remember, next time you want to become an Evil Genius consider asynchronous execution and some time. If it's up to those darn super spies, every second counts!






Latest comments (31)
Very good web page, thank oneself for the exciting material for guaranteed I am going to be back.
kodlogs.net/1/task-delay-vs-thread...
Task. Sleep is a synchronous thread that puts the thread to sleep so it can't be used for anything else. Task, on the other hand. Delay is an asynchronous thread that can be used to perform other tasks while it waits. Refer to this kodlogs.net/1/task-delay-vs-thread...
Good article, If someone stumbles upon this and want to read more about async-await in MVC, take a look
Asynchronous programming in C# and ASP.NET MVC ( With example )
Fantastic explanation and I finally understand this topic! Haven't seen any recent posts of yours but I hope you continue to make some soon :)
Well written Henrick!!
Cool!
A nice thing to know is that if the return type of a method is
Task<int>you can return simplyintand have .net work for you :)code4it.dev/blog/asynchronous-prog...
Nice piece man!
Kudos
I loved the article!!
I've never understood async/await until now, and had to extract all those methods to another one and had it called from Main using .Wait(). I was like "Damn, that is good use and explanation" while laughing a lot
*One Meeeelion Dollars
There are so many misconceptions and bad habits in this article. Please update it with better code examples and clear up the misconceptions like the conflation between async and threads.