C# Async Programming - Part 2: Intro in Task, async, and await

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Applause] [Music] [Applause] [Music] so i just got asked one question regarding the homework and i would like to answer this question for all of you it has nothing to do with async and parallel programming so it's just an x-cursus if you want but i would like to show you how how this is done just to make sure that everybody understands that if i create a console app you don't need to follow along just following your mind if you create a console app in c-sharp and you go let's wait until it has been created here it is uh if we run it dotnet run it will compile and print hello world okay my question to you is where does this consort writeline write hello world to technically a program cannot write text to the screen it can only write text to files and file handles which file is used yes exactly standard out correctly and with a great design for instance dot net run you can redirect standard out to a file for instance my file.txt if i do that i will see nothing on the screen but now hello world is written to the file understand what i mean you can also use pipes for instance if you do something like this and you say pipe find world it will look for the line world and print the line because it contains the line world if we add another line here and we say hello universe something like this if we run it without the pipe it will print hello world and hello universe if we run it with the pipe and the find command the find command reads the output of dotnet run so dotnet run writes into standard out and find reads from where what is the difference of out in stand it in it reads from standard in exactly and this is what you should do so what you can do here in your app the opposite of right line is read line exactly so what we can do is we can say var line equals to console.readline something like this see and then we can print out the line if we do that something like this we can take dotnet run and pipe in or redirect standard in from any kind of command or file in my case i can take the myfile.txt and redirect standard in to the file which contains some text and this should print hello world because in myfile.txt we have hello world so the read line in this case reads from standard in understand what i mean i can do something else i can say echo hello world and pipe that into our dotnet run now we are saying hello world on the console and the output of the echo command is redirected as standard in and now our program with the console.readline reads the output of the echo program understand what i mean so if you take a look at the homework i gave you this data.txt file this one that you have to parse and if you take a look at what i did here in this example i redirected standard in from data.txt therefore you just read the content of the file by using console.readline understand what i mean that makes very much sense because then you can get the output the data from wherever you want if the data is entered by the user that's fine if the data comes from a file that's fine if the data comes from another program which just read the data from let's say a hardware sensor that's also fine with redirecting standard instant out and standard error you can do a lot of interesting stuff does this answer your question yes you have a question you have to read the file in a loop read line will return null as soon as there are no more files available so you can just do a while loop and add all the lines to for instance a list of string and then you have the entire stuff okay never necessarily write because if you do um the read file you have to read a file and with that you don't have to do it yes um however you can also use read from file the methods from c sharp read from file because standard in is just another file stream so if you google that a little bit you will find out that you can use regular file i o to access standard in for instance this is just one method that i showed you here because i've got asked this question okay but i'm sure you will find it out this is one appropriate method that you can use in c sharp additional questions regarding that one no are we fine good very good very good let's close this and i will stick to this app and i ask you to follow along and create the net 5.0 application and also use the lang version preview you already know now how this is done so just create a console app you can call it whatever you want the name doesn't make any difference it should be.net 5 it has to be the language version preview and that's all we need to get started so you have enough time to complete creating the application i will just start with the first few steps i will add a using statement using system.io in order to be able to read stuff from disk if we take a look at the file class and maybe file read something like this and if i'm fast enough i'm yeah i can do it like that then you will find in many cases situations in c sharp where you have two two different functions for doing the same thing one of these functions is just called read all lines or read all bytes or read whatever and the other is called blah blah blah read the lines async and here we have the real difference between asynchronous programming and blocking programming blocking io and non-blocking io now after the theory lesson after the first hour that we spent together what do you think is the preferred way of accessing files database network do you think this version without async or this version with async is the preferred way of accessing io yes correct so in 99 or i would even say 999 of 1 000 cases you will always prefer these methods async that's a naming convention in c sharp in c sharp a synchronous methods which do not block the calling thread are typically called blah blah blah a sync if you write an asynchronous function you're on your own which you might do in the next few weeks maybe not today but maybe in a few weeks you always should call the method blah blah blah async if you do async stuff in this pro in this in this application in this method okay that's a naming convention it's not a catastrophe if you don't but you should try to remember that now if we say read all lines something like this we can give it a path let's try this application okay so let's create another file in this folder i will just say add new item we will do a text file here here text file let's call it yeah text file one is perfectly okay and then we will use i don't know some uh lorem ipsum generator lorem ipsum generator okay lorem ipsum dot de and we have maybe some paragraphs okay let's copy this stuff you can type in anything i just use a generator because i'm i don't want oh sorry i didn't copy everything now i copied everything now i have three lines here any text you can use hello world and nothing else it's perfectly fine it doesn't matter text file one now let's try to access this text file one synchronously text file one is the path dot txt let's take the result var lines and then if we take a look lines is a string array let's iterate over these lines of our line in lines and print it contour right line line got it if i run this guy i forgot something if you get an exception if you run this program please do the following take a look at the video beamer then you can do it on your own right click on the text file one choose properties and then in the properties window down here you use copy to output directory copy if newer that will copy the file to your output directory as the name suggests when you run the application and therefore you can use a relative path here let's run it again and it will print the lines now i'm lucky because read all lines is very very fast i have a solid state disk in my laptop so accessing a local file is pretty fast but still from the point of view of the cpu of the central processing unit even when accessing the file is fast for the cpu it takes forever the cpu runs on multiple gigahertz so it can do millions and millions and millions of operations in a very short time so if accessing the solid state disks take takes only a millisecond something like this for the cpu that's kind of forever understand what i mean it's bored it's locked it's blocked sorry it's not locked it's blocked from doing anything useful so the point is here we have the possibility to change that one from reading it synchronously to reading it asynchronously let me show you how this is done file dot read all lines but this time i'm going to use the async version the async version gets the name of the file textfile1.txt that's the same but it returns a new guy let me see if i can show you that yes this is what it returns a task of string array not a string array like read from file but it returns a task of string array have you ever worked with c sharp tasks before no you haven't ok that's good tasks are the cornerstone the foundation of asynchronous programming in c sharp and you will see tasks from now on until the end of this course year over and over and over again you have to become familiar with tasks and you have to know how to master them it's super super important it's it's one of the basic principles of c sharp it has been there for a pretty long time tasks are in c sharp since the version i think it was four if i can remember correctly in version three of c sharp we got um we got link and in version four of c sharp we got tasks now what is a task a task is not a threat that's the big difference it's similar kind of but it's not a threat a task is just like like a task for a human being let me let me demonstrate what i mean um imagine that we have some cars standing out there and i can ask you to take a look at these cars i can tell you a license plate and tell me whether this car is standing there so what you're going to do you're looking out the window you try to find out the license plate maybe you can't see a license plate so you have to run out there take a look out there come back it will take forever until you get back and tell me yes or no the car is there that will be blocking programming now with the threads what i showed you here it would be different i will tell you go and look for the car but i would use a programming mechanism where i say i give this task to a thread you are a thread in the thread pool for instance and then i do very complex programming to do something else so i can start coding and in a minute or so you come back and tell me the result of your inquiry understand what i mean the problem is what if i want to know a lot of cars i would like to tell you hey look for the car with this license plate and a second later i can tell you look for a second license plate and a third license plate and a fourth license plate and a six license plate because i only have you i have to somehow manage my work i have to create a list of inquiries that i would like to give to you and once you are done and you say i have completed the first one i take something from this list of tasks and give next one to you understand what i mean and that's essentially what a task is a task is not a concrete algorithm it's not a concrete processing thing it's just a request it's representing uh just like the name suggests task that i can start and the beautiful thing is that i can start for instance if i ask you to go to the license plates i can start 20 tasks i can start 40 tasks and these tasks are very lightweight they are not like threads starting 20 threads would be horrible starting 20 tasks is not a problem because a task is just a request it's like a forum where i write down please take a look at this license plate and i put it here on the table and you just go take the first task work on it and once you get back you take a look at the list of tasks and if there is a new task you take the task and you do the next thing there can be many tasks it's not a problem because it's just forms lying on this table and when you are when you're idle when you don't have to do anything you pick up the next task understand what i mean so this read operation gives us back a task and we can use this task object to inspect whether it's already completed we can take a look at this task and the task has a status the status could be waiting to run running completed it it has a status and it also has a result this is the type parameter string array once the task will be completed we have a result and that is the content of the file with our example it would be yes or no whether the car is standing on the parking lot or not understand what i mean that's a task so you can run a huge number of tasks and they will automatically be deployed on the thread pool and whenever a thread in the thread pool is bored it will pick up one task and solve it is that somewhat clear yeah good now what can we do with this task let's assign it var file read task now this file read task is of type task of string array what we can do for instance file read task we can print out the status let me show you what this will result in if i run this guy it will show me see that waiting for activation so i started the task please read the file but immediately after i'm asking for the status and the disk subsystem or the c-sharp the c-sharp common language runtime didn't even start working on this task yet it's like i put this request for taking a look at the parking lot on the table and you didn't even have time to go here and pick up the task it's still waiting for activation so let's wait a little bit okay let's say thread dot sleep let's say 50 milliseconds oh that's an endless amount of time let's wait just one millisecond and then print the status of the task again let's see [Music] see it within one millisecond the task switched from waiting for activation not started yet to ran to completion so within one millisecond the file could have been read yeah it could yeah definitely so if we just do something like this it depends on the speed it really depends on the speed let's take a look yeah it's so fast that just from one step to the other by running this application it switches from waiting for activation to rent to completion because it's simply very very fast the file is already in disk it's not x in memory it's not accessing the disk anymore it's really fast okay good now how can i wait for the task that's simple file read task dot wait dot wait now listen closely this is important i might ask you that in one exam weight is blocking the thread so doing an async operation and then calling weight is essentially the same as calling the blocking operation up here it doesn't make sense we don't want to wait there are only a very few number of cases where you really want to wait but for us in this course we don't wait that's not a good idea we shouldn't do that now can we just access the result the result will be the string array just like here the string array so we can say something like lines equals two is that a good idea listen closely i might ask you that no it's not a good idea because accessing the result like this will again block the thread until the task is done it's just like calling weight and then accessing the result so accessing the result like that not a good idea we shouldn't do that there are very few cases where you really want to do that the good thing is that we have another option file read task dot continue with continue with allows us to schedule a job as in our case an action can you remember what an action is an action is a delegate that gets that returns which data type yes whoever no action not funk correct you you switched in your your uh your mistake was that you described funk not action so if we take a look at this type here it says action of task of string array the return type of this is void we discussed that and what will be the parameter that task the task that just has completed so we can simplify our code a little bit we can say we don't need to remember the task all we need to do is we just call continue with on the result of the read all lines async and then we can write a little bit of code and here here the task will be completed so inside of this continue with we absolutely know for sure that the task is done understand what i mean imagine that you in the evening you go to bed you set up the alarm clock and you think to yourself okay when the alarm clock rings i will stand up put on my running shoes and do some sports that would be some something like continue with we don't start running immediately but we schedule the run for the next day once the current task sleeping is completed and this is exactly what we do now we start a task asynchronously our thread will not be blocked and once the task is completed we can here safely access the task results so what we can do here we can say console.writeline oh sorry something like this we can copy the code from up here just copy these lines put them here and here we don't say file read all lines but we say task.result that's fine understand the difference the job up here blocks the main thread the job down here does not block the main thread because it will only start when this asynchronous method has been completed will be completed understand the difference the problem is if we run that it will not work let me show you let me comment out this first stuff let's see see that no output this is a special case i consciously ran into this mistake so that i can describe to you what the problem is the problem is that the main method when the main met yeah question okay tell us correct exactly you see this here what did i tell you will no longer block the main thread therefore it will schedule the task of reading from file but it will immediately continue i can show you that i can say something like i am here now and if i run this application it will just print i am here now by printing the i am here now i am now slow enough that the task will be completed see it so we have to somehow make sure that the main thread will not exit until this code will have been executed so we can make it very very simple we can for instance say console.readkey console.readkey waits for the user to press any key on the keyboard so if i run this guy it should now work see and it will exit when i press a key that's a very simple solution for our problem that's not the main that's not the main thing that i want to describe the important thing that i want you to understand is async returns a task now you should have an idea in your mind what a task is and then with continue with we can schedule the execution of some code and it will run this code once the task has been completed now what happens if we try to access a wrong file if i run this guy nothing happens no exception see that but now we have it's strange isn't it because if i do it synchronously up here and if i make the same mistake here and i run this guy boom i immediately get an exception and i want to have this exception could not find file so what's the problem here you have an idea exactly we have to manually check if t dot and we have a bunch of interesting stuff there is for instance is faulted so we can check whether the task returned an error and then we can also print out the exception if we want so we can say console.error.writeline and we can say t.exception yeah and maybe do a return here so we have to manually add exception handling just to check it let's run it nice see now we get a could not find file that's what i wanted to have understand the problem do you like this programming model i mean take a look at the simplicity of these four lines and now take a look at the complexity of these lines what do you think is it a good way of programming down here well obviously not if i'm asking you like that the answer is obviously no it's not a good idea to program code like that so we need to find something else we need to get it better and to be honest with c sharp 4 when this came out this was the way of writing code i spent an endless number of hours learning how to write these code i did an endless number of trainings for customers and conferences telling people how this is done and then with one of the next versions of c-sharp something magic happened something magically happened the guys from from the c-sharp language team they came up with two new magic keywords and these keywords are async and await async and await essentially get rid of all this stuff and make async programming at a child's play it will be it will look extremely similar to what we have up here let me show you what the difference is with async and weight and then we will discuss how async and the weight really work it i always call this harry potter programming it's like magic it just works okay that's a good thing let's comment out this complex code take this code again this one the old synchronous code and use that one as the basis of our [Music] of our application so here let's now change that to async that will break our code if we do that we can no longer write for each because lines is now not a string array but lines is a task of string array at that point in time the task reading the file will not be completed therefore we cannot process the results understand what i mean would it be a good idea to just write dot result here it would fix our problem but why isn't that a good idea because result does what yep it doesn't wait to be finished yes it waits it does wait but it blocks the cpu so result does wait it really fixes the problem i can run the application and it will work it really works but it's not good because result will remember that one be not like that result will block the the cpu so that is not a good idea that is not a good fix now let me show you how async and await do their magic you change the result type of the main method to task you write in front of task async and in front of the async method you write a weight boom done a little bit of fairy dust a little bit of magic and it just works that's asynchroid we will discuss how async await works but it just does its job see it works what about the the problem with the exceptions let's make a mistake here let's run it again boom exception just as we liked it so the whole magic and this is what you have to understand of async await is to make handling of tasks as simple as doing synchronous pro programming async await makes asynchronous programming so easy that it now can be used everywhere in the past people would have to write such code especially.net developers they hated this code therefore they didn't write it what they do they wrote this code and this was bad this was not performant c-sharp was known to be slow and then a few years ago this rockstar node.js javascript developers they were used to do async programming in javascript and they they really kicked asses they had javascript and they were much faster than most of c-sharp applications that's crazy javascript shouldn't be faster than c-sharp and their whole magic was because they did asynchronous programming and this is why node.js was so fast and efficient now with async await the game changed i remember that you have a question okay with async await the game change now c sharp developers here can also write asynchronous code without having to deal with the complexity of asynchronous code it simply becomes easy and therefore nowadays c-sharp developers do asynchronous programming and therefore typically c-sharp applications are as fast as node.js for instance if not faster in some regards it depends on what you are measuring that simply doesn't work we need to give c-sharp a chance to see a task to recognize a task so it can reuse the thread for different things this is not done here in this simple example because it's just a console app but imagine this is a web server if we don't do this async with the task and the await we are doing blocking io we are blocking the thread so it's not possible to encapsulate that it's necessary to return a task otherwise it's blocking it's not non-blocking additional questions understand what i mean good good let me show you a bunch of other things okay let's first start by writing a small helper method okay we will call this method or this test this method returns something that we don't know yet okay it is called get data from network async inside of this method we simulate a network call we'll do a network call in the third lesson today okay but currently we are just simulating it by doing task dot delay 150 milliseconds so we are just simulating for we're just simulating a network call we take which takes 150 milliseconds understand what i mean then we are simulating a result of our result equals 42 that is the result from our database and we will return the result so this is just a simulation okay my question to you is what is missing here yeah uh task off integer correct that's the correct return type it has to be a task because it's an async call we do want to use a weight therefore we need the async keyword and what's missing here i'll wait exactly now listen closely that's crucial for your understanding this weight here will not block the cpu this a weight is asynchronous programming this a weight erten a weight is not verten of but a weight is this a weight tells c sharp hey c sharp if you have anything else to do do it paint some pixels on the screen handle other web requests i don't care but once this task in 150 milliseconds in that case one once this task is finished continue from here downwards understand what i mean this is what async await does a weight just schedules the rest of the method and it will automatically be called once the task is done and it will not block the thread it will free the thread it will get to sleep if you want and it will automatically be woken up once the task is done understand what i mean you don't even have to fully understand how c-sharp does this magic just understand that a weight is the important keyword here and async should be the decorator here in front of the method if you remember that everything is fine and guess what when it comes to when we come to entity framework what we will do there is we will always use whenever we do a database query or doing an insert statement or a delete statement we will always do async we will always do async await good now if we would like to call this one get data from network we can do that here we can just say get data from sorry i forgot to add static here static get data from come on get data from network async and if we want to have the result var network result equals what is missing exactly that's the cooking recipe want to call an async method add a weight in front of it and add a sink to the to the method in which your code is currently written it's always the same async means use a weight and a weight requires a sync here in front of the method this is what you have to remember even if you don't understand fully what's happening behind the scenes that's a pretty simple cooking recipe always do the same it will work got it understand that nice what if we want to write that in a lambda function for instance if i take this guy here and if i build this function somewhere in lambda method func off task of int get data from network via lander then we have this lambda stuff we have if we take a look let me take that wave we have no parameters you see no parameters and inside we have the same code as below and now we have a problem because this weight is now within this lambda method and this a weight doesn't care about the async out there because this a weight is now no longer belonging to the outer method but this weight is belonging to this lambda method so where do we put the async now have an idea exactly async this is what i wanted to show you correct this is the correct way of writing an lambda expression with a weight in it good nice this was my goal for the first part of this what's now oh sorry this was my goal for the first part of the coding stuff now we have i think a longer break for 15 minutes and then we will do some real stuff we will write a web server and call some web methods okay enjoy the break
Info
Channel: Rainer Stropek
Views: 35,621
Rating: undefined out of 5
Keywords: C#, CSharp, .NET, .NET Core, Async Programming, HTL Leonding
Id: S49dpEwMSUY
Channel Id: undefined
Length: 44min 45sec (2685 seconds)
Published: Sun Oct 11 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.