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:
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.
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!
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