How to Run Same Task Again C3

Recently I've been looking at ways to improve the functioning of some .NET lawmaking, and this post is nigh an async/await blueprint that I've observed a few times that I've been able to refactor.

Every-so-often, I see code similar the sample below – a single method or service which awaits the outputs of numerous methods which are marked equally asynchronous.

            wait            FirstMethodAsync();            await            SecondMethodAsync();            await            ThirdMethodAsync();

The three methods don't seem to depend on each other in any manner, and since they're all asynchronous methods, information technology's possible to run them in parallel. But for some reason, the implementation is to run all three synchronously – the menstruum of execution awaits the kickoff method running and completing, then the second, and then the third.

We might be able to do better than this.

Let's look at an example

For this post, I've created a couple of sample methods which can exist run asynchronously – they're called SlowAndComplexSumAsync and SlowAndComplexWordAsync.

What these methods actually do isn't important, and so don't worry almost what part they serve – I've just contrived them to practise something and be quite slow, and so I tin observe how my code's overall performance alters every bit I do some refactoring.

First, SlowAndComplexSumAsync (beneath) adds a few numbers together, with some artificial delays to deliberately slow it down – this takes nigh 2.5s to run.

            individual            static            async            Chore<int>            SlowAndComplexSumAsync() {            int            sum            =            0;            foreach            (var            counter            in            Enumerable            .            Range(0,            25))     {            sum            +=            counter;            await            Job            .            Delay(100);     }            return            sum; }

Next SlowAndComplexWordAsync (below) concatenates characters together, once again with some artificial delays to slow it downwards. This method ordinarily virtually 4s to run.

            private            static            async            Task<string>            SlowAndComplexWordAsync() {            var            word            =            string            .            Empty;            foreach            (var            counter            in            Enumerable            .            Range(65,            26))     {            word            =            string            .            Concat(word, (char)            counter);            expect            Chore            .            Filibuster(150);     }            return            word; }

Running synchronously – the dull manner

Manifestly I tin but prefix each method with the "wait" keyword in a Main method marked with the async keyword, as shown below. This code basically just runs the two sample methods synchronously (despite the async/look cruft in the code).

            private            static            async            Job            Master(string[]            args) {            var            stopwatch            =            new            Stopwatch();            stopwatch            .            Start();            // This method takes near ii.5s to run            var            complexSum            =            await            SlowAndComplexSumAsync();            // The elapsed time volition be approximately                              2.5s                            then far            Console            .            WriteLine("Time elapsed when sum completes..."            +            stopwatch            .Elapsed);            // This method takes about                              4s                            to run            var            complexWord            =            look            SlowAndComplexWordAsync();            // The elapsed time at this point volition be about                              six.5s                                      Panel            .            WriteLine("Time elapsed when both complete..."            +            stopwatch            .Elapsed);            // These lines are to prove the outputs are as expected,            // i.eastward. 300 for the complex sum and "ABC...XYZ" for the complex word            Console            .            WriteLine("Upshot of complex sum = "            +            complexSum);            Console            .            WriteLine("Result of complex letter of the alphabet processing "            +            complexWord);            Console            .            Read(); }

When I run this code, the console output looks like the image beneath:

series

As can be seen in the console output, both methods run consecutively – the beginning one takes a bit over 2.5s, and so the second method runs (taking a chip over 4s), causing the total running fourth dimension to be just nether 7s (which is pretty close to the predicted duration of six.5s).

Running asynchronously – the faster way

Just I've missed a great opportunity to make this programme run faster. Instead of running each method and waiting for it to complete before starting the next one, I can start them all together and look the Chore.WhenAll method to make sure all methods are completed before proceeding to the rest of the program.

This technique is shown in the code below.

            private            static            async            Task            Main(cord[]            args) {            var            stopwatch            =            new            Stopwatch();            stopwatch            .            Offset();            // this job will take well-nigh                              2.5s                            to complete            var            sumTask            =            SlowAndComplexSumAsync();            // this chore will take about                              4s                            to complete            var            wordTask            =            SlowAndComplexWordAsync();            // running them in parallel should have about 4s to consummate            await            Task            .            WhenAll(sumTask,            wordTask);            // The elapsed time at this point will merely be about                              4s                                      Console            .            WriteLine("Time elapsed when both complete..."            +            stopwatch            .Elapsed);            // These lines are to prove the outputs are every bit expected,            // i.e. 300 for the complex sum and "ABC...XYZ" for the complex word            Console            .            WriteLine("Result of circuitous sum = "            +            sumTask            .Result);            Panel            .            WriteLine("Issue of complex letter processing "            +            wordTask            .Result);            Console            .            Read(); }

And the outputs are shown in the prototype below.

parallel

The total running time is now only a bit over 4s – and this is fashion ameliorate than the previous time of effectually 7s. This is because nosotros are running both methods in parallel, and making full use of the opportunity asynchronous methods present. At present our total execution fourth dimension is only as slow as the slowest method, rather than existence the cumulative time for all methods executing one afterward each other.

Wrapping upward

I hope this post has helped shine a little light on how to utilise the async/await keywords and how to utilize Task.WhenAll to run independent methods in parallel.

Plainly every case has its ain claim – simply if lawmaking has series of asynchronous methods written so that each one has to wait for the previous ane to complete, definitely cheque out whether the lawmaking can be refactored to use Job.WhenAll to amend the overall speed.

And perchance fifty-fifty more importantly, when designing an API surface, keep in mind that decoupling dependencies between methods might give developers using the API an opportunity to run these asynchronous methods in parallel.


About me: I regularly mail about Microsoft technologies and .Cyberspace – if you're interested, please follow me on Twitter, or accept a wait at my previous posts here. Thanks!

colestuard.blogspot.com

Source: https://jeremylindsayni.wordpress.com/2019/03/11/using-async-await-and-task-whenall-to-improve-the-overall-speed-of-your-c-code/

0 Response to "How to Run Same Task Again C3"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel