Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
September 26, 2019 06:00 am GMT

C Async Await, Simply

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.

alt text

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

alt text

The first thing you'll need, as an evil mastermind, is of course an Evil Lair.

  • Thread.Sleep(x) simply makes the thread wait x milliseconds before it resumes execution.
public static void BuildAnEvilLair(){    Thread.Sleep(5000);    Console.WriteLine("Evil Lair Built!");}

After you build your lair, you're going to need to hire some henchman.

public static void HireSomeHenchman(){    Thread.Sleep(2000);    Console.WriteLine("Henchman Hired!");}

And of course, you'll need to create a mini clone of yourself.

public static void MakeMiniClone(){    Thread.Sleep(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(){    Thread.Sleep(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.

alt text

public static int MakeOneMillionDollars(){    Thread.Sleep(2000);    Console.WriteLine("Million Dollars Made!");        return 1000000;}

Finally, when everything has been completed, we can achieve World Domination.

public static void WorldDomination(){    Thread.Sleep(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

alt text

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, two things happen. A thread is taken from the thread pool and allocated to the asynchronous operation, 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.Run(() =>    {        Thread.Sleep(5000);        Console.WriteLine("Evil Lair Built!");    });}public static async Task HireSomeHenchman(){    await Task.Run(() =>    {        Thread.Sleep(2000);        Console.WriteLine("Henchman Hired!");    });}public static async Task MakeMiniClone(){    await Task.Run(() =>    {        Thread.Sleep(3000);        Console.WriteLine("Mini Clone Created!");    });}public static async Task SuperEvilPlan(){    await Task.Run(() =>    {        Thread.Sleep(4000);        Console.WriteLine("Super Evil Plan Completed!");    });}public static async Task<int> MakeOneMillionDollars(){    return await Task.Run(() =>    {        Thread.Sleep(2000);        Console.WriteLine("Million Dollars Made!");                return 1000000;    });}public static async Task WorldDomination(){    await Task.Run(() =>    {        Thread.Sleep(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!

alt text

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 Lairawait BuildAnEvilLair();// Next, hire Henchman and create a Clone (asynchronously)Task.WaitAll(HireSomeHenchman(), MakeMiniClone());// Now, come up with the evil planawait 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!


Original Link: https://dev.to/htissink/c-async-await-simply-5dh1

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To