That's NOT How Async And Await Works in .NET!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey there and welcome to the Cod wrinkles Channel these days I got very angry with so-called LinkedIn influencers that post misleading stuff especially this time it was this type of post and picture that triggered really my attention this picture suggests that we have here a comparison between synchronous and asynchronous programming obviously suggesting that the part of the right is actually asynchronous programming the problem is it is not async programming at all what you see there on the right side resembling something like a gun chart I don't want to criticize the author of this post but I just want to point out that this information is wrong and it got really T of thousands of likes and comments and everybody was just saying hey great share that's nice and basically most of the people will come to interviews and when they will be asked about Asing programming or acing and the Wai in C they will simply fail the interview because they don't understand what problem aing and the way it actually solves and why what you see in this post is actually not acing programming to prove my point I have recreated here some very basic applications that do exactly what it is described in that picture so we have all these tasks for creating breakfast like making coffee fry eggs friy bacon make a toast add butter to the toast and add Gem and for all these type of methods you see that we have methods and some of them they have this Tas delay because they depend on something else and we'll talk about this just in a few minutes and here we wait for instance 1 second another 1 second 5 seconds and I think the maximum that we wait here is 8 Seconds seconds now this program runs totally synchronously so we don't have any asyn and weight here now let's run it and see how much it takes to run this application so here we started to build to create this breakfast like starting the coffee making machine coffee is ready hitting the pan you see all the task and all the activities that we have for cooking breakfast are taking place here we also have a stopwatch that at the end will tell us exactly how much time this breakfast actually took and you see that it was 17 seconds in this other application I have the exact same thing exact same task with exact the same timings but this time I have introduced this async and the weight and you can see that we basically await all tasks that take some time or we await each method that has a task delay once again we start cooking the breakfast and already you can see that the order basically in which these things happen is exactly the same as it happened previously and just a few more seconds and then the entire application will complete and breakfast will be cooked in our case and will be able to see how long it took and you see it took also 17 seconds so no matter if you use the synchronous version or the asynchronous version it took 17 seconds both times so why is that well because aing and weight is not meant to solve the problem of concurrency or running things in parallel it is meant to solve something else so let's look into what aing and weight actually solves and why it is useful let's have first a look at how actually our processors and our computers work when we develop applications against an operating system could be even windows or Linux it doesn't really matter we have this concept of a process and we have this concept of a thread process is basically an executing application so each application that you execute is executed in a certain process however you also have this concept of threads and threads are nothing else than a unit of four the advantages that we have in desktop applications or generally when we work and or when we program directly against the computer is that a process can actually have or work with multiple threads and this is why we call it multi trading in the past achieving multi trading was something a little bit more complicated that it is right now nowadays in the modern. net we don't really have to care a lot about firing up our own threads and how or what exactly do we do there everything is handled basically by the net if we have this ASN and wa but we need to understand how is it handled the next important thing is to understand how instructions or how our application instructions are executed by a processor obviously this is an overs simpli ification but I don't think that this is wrong at all CPUs run basically on the so-called Fetch and execute cycle they fetch one instruction in a sequence they execute or run that instruction and they for instance return a result the instruction could be for instance something simple like doing an addition or writing something in the console and then the CPU patches the next instruction and basically the threads provide those instructions that the CPU needs to execute obviously on a computer several applications are running at the same time so that's why each application gets what is a so-called CPU time now when an application or a specific thread gets us some CPU time the thread needs to provide something to the CPU to do however if the thread is blocked by something that it is blocking it then it cannot provide this so basically it's time wasted and nothing happens if we think back at our breakfast analogy we can think for instance that we have some actions for instance that we can perform directly like for instance cutting the bread or preparing the ingredients for the coffee or things like that but there are some operations in which we as the cooks we cannot directly impact them like for instance the time that it takes for the coffee machine to make the coffee or the time that it takes for the eggs to get fried and so on and so forth so this means that me as a cook I am blocked in a specific instance and if I'm not capable of kind of like avoiding that block and maybe doing also something else in that specific time if you think about me as the cook as the processor then let's say I have quite a few problems in programming we can think about activities that are basically blocking the trads as activi that take a longer time to compute or to do something than the processor is able to to process like the processor obviously is very fast and does stuff very fast but there are some things in our computer that are very very slow for instance when we read or write to files or or when we work with databases or for that matter whenever we do something over a network that's very very slow and that's why we call that it is a blocking operation the question is though what's actually the problem if we have this type of blocking activities or blocking instructions well as you have seen in a console application right now A actually it didn't have any impact because previously in a synchronous version it took 17 seconds and in the Asing version it took also 17 seconds however if you are developing a WPF application for instance where you have at least two different threads a thread for the UI and a thread for the business logic then if the thread with the business logic gets blocked by such an operation the UI freezes and this is usually when you get that freezing UI with this circling Mouse whe in web applications on the other side the problems that blocking threads actually are causing for our application are not really visible from a first glance let me explain this let's assume for instance that we have a web server and our web server has a dedicated two threads so our web server can work only with two threads now we have a request that comes in one thread is responsible to handle that request now let's assume that handing that request takes 17 seconds just like cooking our breakfast but right after the first request like after 500 milliseconds there comes another request now the second thread will be used to service the second request last but not least after another 500 milliseconds another request comes in but these times unfortunately we don't have any thread available to service that request because the other two threads are blocked by the other request that are still waiting those 17 seconds and this is where the problem comes in so you usually see the problems when you have blocking trades in web applications only when you have a higher Lo therefore to conclude this topic let's emphasize understand once and for all that Asing and awaiting Donnet doesn't solve the problem of concurrency or paralyzation it solved the problem of blocking threads and the problem that blocking threads could cause to your specific application so then why do we have all this confusion with representations like for instance a gun chart for Asing and the weight well because this is a totally different programming Paradigm and it is called parallel programming and parallel programming deals with techniques that we can use to run different things in parallel or in other words run different things on different threads net supports par programming and provides us with a lot of different things that we can use in our toolbox for instance to make sure that we can run different things in parall and here I just want to show you a very basic example of what we can do for instance so here we have the exact same application the exact same concept of cooking breakfast but we have done some tweaks here now the methods that we we have here like make coffee and hit the pen fry eggs they are exactly the same however the things that we have done differently is that when we did do run this application we just here create the different tasks and one way that we could achieve paralyzation probably this is also why there is some confusion about this is that we can use this task class for instance and we have this when all method and when we use this we can simply fire and forget all these different tasks that we have here and they will be executed in part so let's run this application and this time we see that even the tasks that we have here have started at the same time the three task that we having this when all and obviously this optimizes because it runs everything in parallel and instead of 17 seconds we have 9 seconds so we basically are 50% Faster by managing to do this in parallel however I want to emphasize that you can even run methods in parallel that are not as synchronous so that are not task for that we have different Library or classes in net like the parallel and we can use the parallel for each or the parallel for to fire up tasks like this fire and forget before we wrap up just yesterday I got angry again and with another LinkedIn influencer that created a post that said basically also with the graphical representation that running a weight like we do here with a weight make coffee a weight fried eggs it's actually a code smell and instead of doing this like awaiting different things we should use this task when all that's obviously once again totally wrong for so many reasons for sure if you need to run these tasks like fire and forget task then running them with task and all might be actually a good option however in most of the cases this is not happening and the reason for this is that this task should happen usually in a certain order like for instance we want to First write something in a database then we want to send a notification so we want to know exactly the order in which different tasks are executed if you run these tasks to an all you don't know exactly what that order will be so you don't have full control on that but there there are even bigger problems with this because if some of these tasks here like this one or this one throws an exception you don't know exactly which task did throw the exception so exception handling is way more difficult when you run this task when all so that's another reason why we should be very careful when we actually use this task when all and make sure that we really use it only as a last result when we really want to run heavy things in parallel and then we are aware of all the downsides that we have of doing so so if we think about the definition of a code smell actually when you look into a code base and see task when all that's actually more of a code smell than having several different awaits because this can create a lot of different problems in the application and leave place for bugs and defects while the await is kind of like much more straightforward obviously if you take take a deeper look at the code you can realize that using the task when all is fully Justified and it's okay and we have also the mechanism in place to handle the exception so we are aware about all the stuff that could potentially go wrong and in that case obviously we can leave it like this so there are scenarios where we want to do this or we want to run it with task when all this being said if you think that this video was useful for you don't be shy and hit a thumbs up button and like it this will make it easier to discover for others that might find it useful as well and if you are not subscribed to the c channel make sure that you hit the Subscribe button so that you don't miss out on anything else that we do here on this channel including a lot of different live streams and if you have any idea or any question or just want to get in touch with me don't be shy and head over to the comment section and leave a comment and I would be more than happy to get in touch with you this being said thank you very much for watching and until the next time I wish you the very best
Info
Channel: Codewrinkles
Views: 9,708
Rating: undefined out of 5
Keywords:
Id: 5CbWSUQ59fA
Channel Id: undefined
Length: 12min 25sec (745 seconds)
Published: Fri Jan 12 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.