When to Start Lovenox Again Post Operatively
Recently I've been looking at ways to improve the functioning of some .NET code, and this mail is about an async/await pattern that I've observed a few times that I've been able to refactor.
Every-so-often, I see code like the sample below – a single method or service which awaits the outputs of numerous methods which are marked as asynchronous.
wait FirstMethodAsync(); expect SecondMethodAsync(); await ThirdMethodAsync();
The 3 methods don't seem to depend on each other in any way, and since they're all asynchronous methods, information technology's possible to run them in parallel. Just for some reason, the implementation is to run all iii synchronously – the flow of execution awaits the first method running and completing, then the second, and then the third.
We might be able to do better than this.
Let's await at an example
For this post, I've created a couple of sample methods which tin exist run asynchronously – they're called SlowAndComplexSumAsync and SlowAndComplexWordAsync.
What these methods actually practice isn't important, and then don't worry nigh what function they serve – I've only contrived them to do something and exist quite slow, so I can observe how my code'due south overall performance alters equally I do some refactoring.
Starting time, SlowAndComplexSumAsync (below) adds a few numbers together, with some artificial delays to deliberately slow it downwardly – this takes about 2.5s to run.
private static async Job<int> SlowAndComplexSumAsync() { int sum = 0; foreach (var counter in Enumerable . Range(0, 25)) { sum += counter; wait Task . Delay(100); } return sum; }
Next SlowAndComplexWordAsync (beneath) concatenates characters together, again with some artificial delays to slow information technology down. This method usually about 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); await Chore . Delay(150); } return word; }
Running synchronously – the slow way
Obviously I can but prefix each method with the "look" keyword in a Main method marked with the async keyword, equally shown below. This lawmaking basically only runs the two sample methods synchronously (despite the async/look cruft in the code).
private static async Task Principal(string[] args) { var stopwatch = new Stopwatch(); stopwatch . First(); // This method takes about 2.5s to run var complexSum = await SlowAndComplexSumAsync(); // The elapsed time volition be approximately 2.5s so far Console . WriteLine("Time elapsed when sum completes..." + stopwatch .Elapsed); // This method takes about 4s to run var complexWord = await SlowAndComplexWordAsync(); // The elapsed time at this point volition be about half dozen.5s Console . WriteLine("Time elapsed when both complete..." + stopwatch .Elapsed); // These lines are to testify the outputs are every bit expected, // i.eastward. 300 for the complex sum and "ABC...XYZ" for the complex discussion Console . WriteLine("Result of complex sum = " + complexSum); Console . WriteLine("Result of complex letter processing " + complexWord); Console . Read(); }
When I run this lawmaking, the panel output looks like the image below:
Equally tin be seen in the console output, both methods run consecutively – the beginning one takes a scrap over 2.5s, and so the second method runs (taking a bit over 4s), causing the total running fourth dimension to be just under 7s (which is pretty shut to the predicted duration of 6.5s).
Running asynchronously – the faster mode
But I've missed a great opportunity to make this program run faster. Instead of running each method and waiting for it to complete earlier starting the next ane, I can start them all together and expect the Task.WhenAll method to brand certain all methods are completed before proceeding to the residual of the program.
This technique is shown in the lawmaking beneath.
individual static async Task Main(string[] args) { var stopwatch = new Stopwatch(); stopwatch . Start(); // this task volition accept most 2.5s to complete var sumTask = SlowAndComplexSumAsync(); // this task volition take about 4s to consummate var wordTask = SlowAndComplexWordAsync(); // running them in parallel should accept about 4s to complete await Task . WhenAll(sumTask, wordTask); // The elapsed time at this point will only be nearly 4s Console . WriteLine("Time elapsed when both consummate..." + stopwatch .Elapsed); // These lines are to prove the outputs are every bit expected, // i.east. 300 for the circuitous sum and "ABC...XYZ" for the complex word Console . WriteLine("Result of complex sum = " + sumTask .Upshot); Console . WriteLine("Result of complex letter processing " + wordTask .Effect); Panel . Read(); }
And the outputs are shown in the epitome below.
The total running time is now only a scrap over 4s – and this is way meliorate than the previous time of around 7s. This is because we are running both methods in parallel, and making full use of the opportunity asynchronous methods present. Now our full execution time is simply equally slow equally the slowest method, rather than being the cumulative time for all methods executing i subsequently each other.
Wrapping up
I hope this post has helped shine a niggling light on how to use the async/await keywords and how to apply Task.WhenAll to run independent methods in parallel.
Apparently every case has its own merits – merely if code has series of asynchronous methods written so that each one has to wait for the previous ane to complete, definitely bank check out whether the lawmaking can be refactored to use Job.WhenAll to improve the overall speed.
And maybe even more importantly, when designing an API surface, keep in mind that decoupling dependencies betwixt methods might give developers using the API an opportunity to run these asynchronous methods in parallel.
About me: I regularly post virtually Microsoft technologies and .Net – if you're interested, delight follow me on Twitter, or accept a look at my previous posts hither. 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 "When to Start Lovenox Again Post Operatively"
Post a Comment