Asynchronous Programming in .NET 4.5 (async and await)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right so let's go ahead and get started like I said my name is Michael Kennedy I work for development or as an instructor and here today we're going to talk about c-sharp 5 which was released is about to be released in October I'm guessing with Visual Studio 2012 and all that stuff and we're going to also talk a little bit about the task class in api's that will introduced in dotnet 4 because as you'll see the C sharp 5 parallelism concepts are built entirely on top of what was introduced in c-sharp 4 and my experience is that not too many people have a lot of experience with that so we'll spend just a few minutes in the beginning getting into that so first thing I want to do is actually give you guys a little bit of a poll and just ask you know what is your background so that we can aim that right so let me go ahead and I'll launch this poll here so if you could just fill out really quickly what your background is all right excellent I see one of you are already using async in a way that's really cool some of us are doing a little a little threading not too much excellent some people are just using the older threaded ap is very well okay alright some guys are doing the TAS stuff excellent so I would say probably 70% of you are either doing system dot threading dot thread type uh parallelism or or none or a little bit down there okay so here let me share the results with you guys so that's how it breaks down and is not too surprising to me the traditional dotnet api's have been around since you know 2001 2002 when dotnet first came out there have been several evolutions of new api's that tried to make it a little easier a little more manageable sometimes relying a little bit less on using classes extra threaded classes and just hooking on to existing classes for example if you have like a web client you wanted to do a download there's at least three ways in which you could do that now and they've sort of built up over time they didn't start out that way okay so one thing that we're going to see that's really great about the task classes and then of course in c-sharp v builds on it that as well is that these are unifying api's they sort of encompass all the functionality that you might have seen in all the older API so the threading Club the thread class the delegate dot begin invoke style that I the eye sync result style programming all those different things you will see that we can fold into just this task class and then we'll build on that with the c-sharp five okay so let's go back to my screen perfect thanks for doing that when I see there's also a question let me see what that's about older API okay great thanks go away okay so oops why do we care about threading in the first place here's a really interesting graph and if you look at the date on it the the the date is from an article a long time ago but the graph has actually been updated with up to 2010 so for a long time we were able to build these applications and if the application wasn't fast enough all we had to do is just wait six months a new processor would come out our machine to be twice as fast and all of a sudden our application seemed plenty fast and we just kept on going and people sort of referred to that as the free lunch all right but something really strange happened around 2004-2005 this this dark blue graph here this is the CPU clock speed and that was what people sort of thought of as Moore's law but the real honest Moore's law was about the number of transistors right that's the green one so people thought of you know well Moore's law is doubling the speed of our computers every six 18 months or something like that and at some point it just stopped you know they hit a physical wall where you can't go faster right if you start to burn up the chips you have no more space to put you know things in there together and basically they change the way in which computers are sort of increasing the processing power right so you can see a lot of computers sort of hit this limit they even slowed down some now I have a brand new computer and it has a whole bunch of transistors but it doesn't have much higher clock speed than the stuff from 2005 but let me see if I can pull up a process explorer here for you the way they're doing that is of course by having multiple CPUs alright so here I have 8 cores on this machine and they're all you know kind of doing stuff I've got a couple recordings going and stuff that and screen sharing takes a lot out of it but if we want to take advantage of this processor we can't just write single threaded applications we need to write parallel applications that will actually leverage all these different cores because if I have one app and it's just completely pounding the CPU the most I'm going to get is 12% usage out of this and this is just the tip of the iceberg because if you look at the the chips coming out of Intel and AMD going forward they're going to have many more cores than just eight alright so if you've got a hundred and twenty eight core machine and you don't do parallel programming the most you're going to be able to leverage it is less than 1% even if you're just you know completely pinning the CPU there okay so basically around 2004-2005 we've had to as developers start to take multi-threaded programming series not just for you know sort of server based applications or scenarios where you don't want the UI to be hung up so you want to do something in the background but just simply to have our applications leverage the hardware they're running on ok so if by the way if you want to find this article just google the free lunch is over and and that'll do it ok so our agenda for today we're going to first talk about the task class which was introduced in c-sharp 4 and that's basically the fan national stuff we'll see that see sharp 5 introduces two new keywords async in a weight that work together and they really could have gotten away with a single keyword but it it would make sort of debugging harder so they make it a little more explicit with this second keyword here so what we're going to do is we're going to first look at the task class and then we're going to see how we can build on it and these async and await keywords are really super simple but what they're doing behind the scenes is there's a lot of compiler magic and you need to understand the task stuff pretty well ok so around 2010 we had a dotnet for introduced and dotnet for came along with this task class so the task class is really similar to the thread class that we've known for a long time since 2001 2002 and it takes a delegate and you can say start on it just like the thread but there's a whole lot of features added on top of it that make it much nicer than just the thread class for example it has it can return values you can compose them you can sort of chain them together and so on but in this simple example it looks kind of like that so let's just go do a real quick demo here all right switch over to visual studio and I want to show you a couple of key points about the thread class okay so here's Visual Studio 2012 but you could just as well do this in Visual Studio 2010 there's no reason you can't it's just you know dotnet for stuff alright so the first thing I want to do is just write a sort of a simple parallel program imagine that we've got something like a travel website like Expedia and a request is going to come in to our site to our system and it's you know we're going to have a couple of different things we want to do somebody's going to say I'm booking a vacation so they're going to want to book a hotel a plane and a rental car all at the same time but you can bet that the rental car company doesn't care what the airline does alright these systems are 100% independent so we should be able to paralyze them you know book the car and the hotel and the plane all at the same time so we're going to use the task class to do that all right so let's just do a quick bit of coding here so we'll say car and let's suppose this returns an int ID let's call it car ID equals that really quick and then we can do this little trick we can hit a control period in Visual Studio and it'll actually write the function for us so let's do that for hotel oops hotel ID here and we'll do the same thing for what's left the plane okay plane so we'll let Visual Studio write those three functions now as you can imagine not implemented is probably not what we want to do we're not really going to call some web services just to keep things simple we're just going to make the system run a little bit slower just to simulate a web service but let's do this let's say console.writeline booking plane dot dot on the bottom we can say done with plane and let's go ahead and also create a static random and whoops just to simulate some sort of ID or some so we'll say return R and that next of 100 all right so there's a sort of a fake web service call and let's pretend this takes a little while so instead of doing real work I'm just going to say thread dot sleep and for the plane let's say the plane takes five thousand five thousand milliseconds five seconds for the hotel let's say this is going to take eight and better put the right words here toe tell and then lastly for the car let's say that it takes only three seconds okay and also let's time this will create a stopwatch class I'll say stopwatch I got to import that namespace s W equals stopwatch start new and the bottom will just say something like console.writeline finished in totally zero second and we'll just a stopwatch elapsed milliseconds turn those into seconds divided by a thousand okay we're not doing anything with the IDs yet well I'll figure that out in a little bit okay so if I run this it shouldn't surprise you there's no threading going on I just booked the card takes five seconds of books a hotel which takes 8 seconds and we wait and then finally a books the plane which takes five seconds or three seconds I think the car was three seconds yep so the total time it takes of course is the sum of all the parts all right but because the car has nothing to do with a hotel which has nothing to do with the plane we should be able to do these all at the same time so let's convert this to use tasks so I'll do this here comment this out I'll say this is the serial way and so when you guys get these code which of course I will give to you you can you can see all the different ways so we'll see this in a couple of ways here so instead of doing this let's actually create some tasks so I can say I can say tasks now because this what the result of this booking a car is an integer we can actually say we want to create a task of int and that will store the return value which will be the car ID okay and you can see that that's coming from system about threading tasks dot task which is a different name space than the old one so we've got to import that at the top all right we'll call this car task equals and then kind of like our stopwatch you there's a factory way to create these that are this a little simpler if you want to create and start them at the same time so I could say task not factory dot let's start new event and give it the book car like that and then you just give it the function to call we could do the same thing for the hotel make sure I get these all fixed for you okay and then let's do one for the plane okay so you guys might be thinking all right excellent we're going to be able to do all these at the same time we have these three separate tasks they're going to run and it should take this not the sum of the pieces right not 16 seconds but it should take just the longest one we only need to wait until the longest one is done the other should already be done since they're all happening at the same time but it turns out that there's a feature of the task and that you'll see here in a second so let me go and just run it and you might be surprised how quick we can get this to go okay so in two milliseconds we finish booking the car in the hotel all right so what happened well it turns out that these these threads that are created here these all create threads they come out of the thread pool and the thread pool threads are what are called background threads and they don't keep the main process alive so if if the main thread exits then these background threads are aborted you can see that here that we were booked in the car in the hotel and whoa those never finish but we still exited so the thing with tasks is you have to wait for them to finish okay so there's two ways we can wait we could say tasks outweigh all hopes not win any when all the wait all win all is the new version we say car task hotel task plane task and just like that okay so that's one way to do it and that's something you do a lot of time if you have a void void peace so here you can see now we're waiting for them to finish and they should finish in order of however short they are like the shortest one first and the slowest one last so you can see that painted finish in the same way let me see if I can run them a different order because I wrote them in slowest worse so let's run the hotel first and then the car you should still see the car finished first alright so cars the shortest it was three seconds the plane was five seconds in the hotel was eight seconds so right they just finished in whichever order they are they take wait let's put hotel last actually are sorry they're like this yeah I guess they all just start at the same time sorry that's just ran out there we go alright finally got the plane in the hotel to switch places but you can see it's taking 8 seconds and the reason it takes 8 seconds is that's the longest task ok so this is an interesting way to wait for me could do this but we could also do this we could say console.writeline finished booking car ID writing card car ID equals curly 0 Hotel ID was curly 1 and plane ID right these are like your confirmation numbers or whatever that you would get and I could just do this I could say car task dot result and that's that integer that was returned because we have a task event this is sort of the return value here so we could also say hotel task dot result and plane tasks that result ok and what will happen is we're going to run through these start them off straightaway and then we're going to get and try to write out this line but we're going to the runtime will try to access the value of result but result is not available so it's just going to do exactly the same thing as waiting it's going to wait until the car is done and then it's going to go and try to access the value of hotel tasks that result it's going to wait until that's done and then same thing for plane so we don't actually need to wait if we're accessing all the values ok so you can see it didn't just run to the end it's waiting waiting for the car to be done then the plane and the hotel all right and then we get these IDs back and I forgot an equal sign but you get the point right okay so that's almost enough foundational stuff on task there's just one more thing what if I wanted to do something like this what if I wanted to say when the hotel is done I need to go do additional booking like I need to you know make sure I I set some preferences like maybe you've set up in in my Expedia type of website that you always like a room with a great view and so we could say set up something that after the booking is made we could go back and you know send something to the hotel so if we wanted to do that we could say hotel task dot continue with and we can chain additional tasks into it and you'll see that the C sharp v compiler does all sorts of magic with this concept of continuing with additional pieces of work okay so let's say tasks this can be just a void task here we'll say Hotel follow-up task equals continue with and what we do is we give it a delegate of some sort and probably the most natural thing to do is to just give it probably just a lambda expression so what I can go down here is I can say what's always passed in to continue with is the previous task so basically Hotel tasks will be passed in so we'll say tasks approve goes to and what are we going to do well we got to do something with it so we'll say console.writeline adding view note for booking truly zero comma past previous oops tasks previous ID okay now we should probably wait if you have just one task you want to wait on you can wait this way so what's going to happen is this is going to run it's going to take five seconds or however many it takes and then when it's done it's going to turn around and run this task we don't have to wait for the hotel task because this one the second task won't be finished until both itself and the hotel tasks are done okay so we can just do this wait here alright so let me just run it you guys should see that working well and then we'll switch over and talk about c-sharp five so right we don't see that message that the we're setting the hotel right okay so we done with the hotel then we added the book the note for the booking of one and you can see Hotel IDs five what did I do wrong here oh I said ID whoops result is what I wanted so here I'll run it one more time all right so this is probably a good place to stop and ask questions here you can see hotel booking sixty-three hotel ID is 63 so if you have any questions sorry we only have one way audio here but you can throw it into the the chat window with a question window and I'll keep my eye on on the little notifications to see if some of those come up if they don't then I'll just move over C sharp five all right excellent so we create these tasks you can either say task task equals new task and then start it or you can say task stop factory got start new that's I like that's a little simpler it's also a unifying API there's about five different ways before dotnet for that you can create threads every single one of those can be represented by tasks and so you have this nice single way of doing things this is very analogous to what WCF tried to do for all the previous networking api is like used to have Message Queuing and sockets and web services now you can just do all that with WCF well task is like that for all the different ways to do threading you have background threads you have main threads right here we're creating tasks running a long-running task which is like equivalent to the thread classroom previously okay so excellent now we're ready to talk about c-sharp five so c-sharp 5 it turns out takes a broader perspective of what parallelism is and what asynchronous programming really means so it still supports creating threads and doing all the stuff that you just saw but it also goes a little bit farther ok so I just want to set you guys get your mind in the right perspective here so I went over to Wikipedia and I looked up what is asynchronous programming what is a synchrony mean right and so they sort of talked about events and actions and they say asynchronous events are those occurring independently of the main program flow asynchronous actions are actions executed in a non-blocking scheme allowing the main program to keep running so nowhere in this definition do you see threads and you're going to see that c-sharp 5 actually supports sort of the single threaded type of parallelism and there's a lot of advantages and GUI based applications for that and then also support sort of creating background threads and using the thread pool and all those kinds of things ok so C sharp 5 and VB both introduce these new keywords async and await what they do is they let us build applications as if they were serial right as if they were just single threaded applications and then go put a few keywords in a couple of places and then make them multi-threaded but not change the way that we write our code because it's really difficult for us to reason about program flow and asynchronous ways like when we created that task and then when the program runs and it runs this book hotel then it comes back and then it continues with this other delegate which might call other delegates it it turns out to be very hard to debug but really especially mentally to keep keep clear what's going on in the right bug-free code and so what we can do with c-sharp 5 is we can write code as if it were just the basic non multi-threaded code and then turn it into a parallel version using these these keywords okay so it's continuing on with like sort of exploring the different ways we might do threading the example we just did with Expedia looks like this right we have some kind of request comes in and we kick off three separate thread on three processors we do them all in parallel and then we wait for them to be done right here we wait and then we gather up the results and we keep going so this is a perfectly good example of a synchrony all right now in our world we actually blocked waiting for the results but that was a choice our main thread had it didn't you know it's not like the threads actually blocked the threat the main thread okay but another example might be something like this imagine I have three large pieces of work one of them is represented by blue one is green and one is red so if I could take these big pieces of work and break them into small little bits that could be done independently and I would intersperse them on say like the Windows message pump here and then the message pump would pull them all out and do a little bit of blue worked a little bit of green work do a little the red work and keep going for each part of it if those are small enough slices they would feel like it's continuing to run just fine all right even though there's little box words kind of locked up it still would it be effectively what we would consider asynchronous all right so you'll see that C sharp 5 actually supports both of these okay so what's the trade-off well if we choose the top way we have a lot more thread safety concerns because we actually have stuff happening on multiple threads at the same time right so we've got to be really careful about race conditions though the programming model is more difficult right we've we've got to kick off a bunch of things and then gather up the results that's that can be really tricky and so on the version on the bottom is simpler one of the benefits down there is if we're working with a say UI controls like WPF controls or Windows forms controls or something like that or even Metro by the way this is all in Metro windows 8 as well then we won't even though we'll be able to simulate parallelism and keep things running we won't actually have to worry about doing things like moving the call back on to the main UI thread because if you've ever tried to access a control from a background thread that's that doesn't work so well right you get an exception ok but one of the drawbacks at the bottom one is you don't actually get more you don't actually take advantage of the 8 processors on my machine right you're still just doing single thread stuff so you're still only at most leveraging 12 percent of my computational power all right so you might choose one over the other based on that all right so give me some examples right is what you're asking I'm not sure if everybody can see this but it says please talk about some examples ideal situations when when one should be used over the other so what I would say and it'll be much clearer after you see this we're just about to jump into a demo and do this if you're not doing stuff that's computational that really is trying to leverage the CPU I would prefer the bottom stuff if you're doing GUI programming because it's just simpler really what you're trying to do is not block the main UI you'll find there's a lot of stuff you're waiting on in a web windows application so that you might make a web service call but you're just waiting on that socket to receive the response or you're talking to a database and you're just waiting for the return value from the sequel query and so on okay so those scenarios we could actually just let the main thread just keep running okay yeah what is the newest way either task racing can await another question and how do we access the shared data okay so let's that's a good question let's switch over and I'll show you that a sinking away is definitely the newest way so let's just switch over to visual studio and I have a less simple example here okay let me go to this one here and this one starts from a little bit of a project that I had before and let me I think I realized I was playing with it just a minute ago I'm pretty sure aya I should not have changed it but I did so let me just make one quick change here sorry about that one more apologize about that okay so let me just run it first then we'll come back and talk about what it is so this is a WPF application and what it's going to do is it's kind of like a search engine like a client-side Google or whatever so what it's going to happen if I type in here maybe I want to know about the fancy new tablet the Microsoft just released so I could go do a search about surface so let me go and show you what's going to happen when we click on that so it's using mvvm here's the main window view model we're going to go down here we click search what it's going to do is it's going to go to the entire Internet look at all the URLs there and it's going to loop through each one of them download them on demand do a basic search basic keyword search for the contents and then the ones that it matches it'll show them alright so this the entire Internet hang show you guys is basically like 20 or 30 News based websites okay but the thing is this method is going to be called when I click the button and it's not going to return until it's downloaded and processed results from all 30 websites so let me give this a shot and you guys will see what happens so if I click search you can see that the color sort of still stuck on what it was for the Highland I try to move it it's not going to move it's totally locked up but the program is not broken it's actually doing the download right now eventually we'll see that it'll come back oh there it goes hi it must have not found anything let's go search for iPad all right so it's searching thinking away okay great so finally it's gone and got the results you know a million iPads were sold last quarter unbelievable wired comm is talking about the iPad we can double click it it'll like pop open a browser and show us you know so presumably someone here iPad alright so this is the article it must have found when we went and searched that okay so the the app is working and it turns out that it's not very computationally heavy either because really all it's doing is waiting on 30 website requests so this is sort of a really good example where we might go and use the new features of c-sharp 5 okay so they're deceptively simple let me show you how we do this what we do is we can go to this method which is just being called directly through the command binding in WPF through the mvvm data binding command binding type stuff and what we can do and we can find the part where all the slow stuff is happening it's line 82 right there we can just go to definition on that and you can see we're using the web client and then dotnet 4 5 a lot of these classes that might take a while I've been updated to have what are called task async methods so we've we've had a client I could say begin downloads again I guess none of this one with web requests you could say begin get response or you could say get response async this one you have a download string async all right but before this you're supposed to say client dot download string completed and you have to subscribe to an event and that event is fired and so on so there's these previous ways in which we could do this in a parallel way but it turns out to be very difficult to create composable software alright so if one thing is calling another thing that's called asynchronous and it's calling another thing that's asynchronous it's really hard to make all those pieces fit together well and it turns out c-sharp 5 is much simpler because you write what looks like top to bottom procedural code with no threading and then you just sprinkle some magic c-sharp v fairy dust keywords on here alright so the first part is to switch this from download string to download string task async ok so we're going to switch this to task async and it's going to return a task of string ok and that's the task that we've seen the whole time we can go do tasks stuff with it however you like ok but what we're going to do is we're going to use the new keyword when say oh wait I can see it's got little squiggly lines and stuff and says you can't do this this is just a convention that they put into c-sharp 5 it technically could have been done without it but they said if you're going to use this word you need to sort of declare your method as being an asynchronous call so you have to say async up here and then you can see that a weight turns blue and we can now do this now there's something really interesting here if I hover over this you see tasks of string is what comes back but on the left side after we process in a weight what we get is var is actually a string so even though download tat a string task async returns a task of string the await keyword says you don't actually care about tasks that's the mechanism by which we make this work but you don't care about tasks you just want the result you're waiting for the result and give me the results so what you get out the other side as a result string this case ok then the other thing that's weird is this is a string let me go ahead and write it a string now so it's really clear we're returning a string here but it says that you have to return a task out of your async methods so what this really needs to be is a task of string but where it's interesting is we say return string and yet the return type is task of string and there's no compiler warnings right if I press build it's totally happy well ok it's not totally happy because the method the methods that we're using this one are broken but you can see there's no errors in the downloader class file it's only in the view model ok so this is basically C sharp 5 which do is you work with methods that return tasks you typically tasks of results you could await a void task but you would just have no return value but you await the result you get the actual result as the direct value and then off you go so let me run it first and then I'll come back and dissect what's happening here for you but there's there's this other problem because back up here where we are calling this it said this was expecting to return a string here right that's that's how it was working before but it no longer returns a string so what we need to do is say okay fine well I actually wondered the value of that so you kind of got a walk your way up the stack and say I want to use a weight here and so in order to use a weight I got to use a sink just like that then it should be good to go alright now we'll compile and something really interesting is going to happen so it's going to run down here I want to click this button it's going to run just normal main thread until it hits this await and then it's going to say alright well I this is not done I've got this task back I'm waiting for the task to complete but it's not done so it's going to release the main UI thread to keep working and it's going to convert the second half into a continue with and when the task is finished it's going to put a message on the message pump it'll pull out and it will continue processing this bit and it gets a little more complicated because we're in a loop so you can kind of think maybe well it'll just run down within the loop then it'll turn it into another continue with and another continue with and so on and we'll look at this in a disassembly in a minute but let's just run it and see it working okay so we search for iPad for run see it's moving results are coming in and we've hit CNN now we hit seen it and now we got breaking news from a place which is what MSNBC or something okay look at that we've done almost no work we've just put a sink in a wait two different locations and down here in the downloader we've used convertor from the download string to download string tasks async and so what the c-sharp compiler does is it basically writes the code that we wrote in the first example we saw in the console application it says ok well we need to break this into a bunch of tasks and the stuff that happens after the task is done is to continue with but it adds on some additional magic to actually keep this happening on the right thread ok so what's really interesting here is when I go and search for like search for truck or something ok so when I go do this search I'm still able to update the bat the the UI from the background what from these sort of asynchronous two pieces of my application I don't have to you know check and see is it a background thread and cycle it back over to the main thread and so that saves us tons and tons of work we could actually go and ask it we could say something like let's say to bug that right line whoops current thread ID we could say thread whoops sometimes intelligence gets too helpful dot a current thread dot a managed thread ID ok let's try that see that here you can say that here and let's also say it right in the constructor where we know it's on the UI thread ok which is right let's say right here ok so if I run this into bugger it should always have the same ID there's no extra threads in other words the kind of work we're doing is this bottom version of asynchronous programming not the top version there's a ways to do the top version and with async in a way but what we've done so far is not it ok oh and you cannot update it while it's running add that makes perfect sense okay so go and run it and whoops let me run it in the debugger so you see the debug output let's search for iPad again and down here in the output window you could see right in the beginning current thread is nine I have a press go I guess not there we go now it's going so see all the stuff before we download this the content after we download content it's all the same threat we're not doing multi-threaded programming we're doing asynchronous program which is a broader concept right okay I so let me undo those guys we don't want that messing up our code here and excellent okay so let me show you one more thing I'd like to do what I would like to do is I would like to look at this method update stats so what I want to do is every so often I would like to go and ask the search system which is doing the download how many downloads have are you have pending what thing are you currently processing so if you go and look at here it says idle at the bottom and you may have noticed it always says idle even while it's downloading it says idle and so there's this update stats piece that's supposed to update that okay so let me just go and call it at the beginning right and the constructor right when we create our application we'll get started and do this okay but notice while true when do you think that's going to return never right it's it's an infinite loop so if I go at five and I run this well it's starting our app and our app is running you can see web searcher down here is actually running but it's it's not showing the window the reason it's not showing the window is it's never even returned from the constructor if we hit pause then go up the call stack one bit right here you can see it's still stuck in update stats okay so that's not surprising you know you've all known that if you write a while true loop and you never break out of it well you're kind of stuck there but let's do something really interesting here let's say we don't want to do this too often so we can say that some say task delay we can say we want a task that will complete in 200 milliseconds now that seems completely useless but we can put a weight in front of it and of course this means when we have a async here if we put a weight in front of it what it does is it's going to say okay program run to here and then release program control for 200 milliseconds and then run this little bit of code and then release program control for 200 milliseconds and so on now in the constructor I didn't update how I'm calling this I'm not doing anything different I just call update stats but you're going to see something pretty amazing first of all we're still calling it in our UI is now working if I say I pad and I search watch the bottom the status bar 23 pending and researching Fox News MSNBC so we've essentially kicked off like a background task that every 200 milliseconds is checking the status of the search engine and updating it and yet it's doing it on the UI thread it's created this this mechanism by which every 200 milliseconds the Windows message pump goes and continues working right so that's really really interesting and if you look at the CPU usage it's still super super low this is you know that adds almost no overhead because all right the amount of time that takes to run versus 200 milliseconds is like you know zero point zero zero zero it's super super small okay so that's that's a really interesting use we have maybe 14 minutes left let me look at the slides for a minute and sort of catch us up there and then I'll show you one more one more way to sort of go down this more bore towards true parallelism we won't actually go and do too much of this but one thing that you notice is if I go and run this over here the output window it shows us what what it's searching let's just do a clear okay so if I go search for iPad up here or if I could spell it right all right you'd see its first doing CNN then Fox News then MSNBC then NPR then Boston news then Dallas news it's doing them in order right there's no actual parallelism like like we saw with our Expedia example that really had parallelism stuff happened faster this is no faster than before it just lets my UI update and my screen get moved around and if I wiggle it apparently all in my original studio there we go okay so the last thing in this example to do is to actually make it do stuff in parallel okay so it turns out that that's not hard at all we just have to rewrite one of our methods here so the thing is this method is asynchronous but what it does is it runs down and it waits for one thing to finish and then it processes it and then it starts another one and waits for it to finish and then process it starts another one waits for it to finish and process it okay what we need to do is start them all and then when any of them are done then we want to actually go and process them all right so what we have to do is write two for loops okay and this turns out to be a while loop at the bottom and I just said let me just say I'm false for a minute okay actually true just so it doesn't get grayed out by resharper okay now there's a few things we got to patch up here but let's do this let's create a list of tasks oops cut import tell assists too much list of tasks downloads equals new list so what we're going to do is instead of a waiting on these right away we're going to do this we're going to say download so it's downloads got add now you first we'd start out writing something like this right just gather up all the tasks and then later on we're going to wait on them but it turns out we have this problem because we actually need two pieces of information to process the result we need what the URL is and what the content at the URL is so we can search it right we need to know the URL so if you double click it we can take you there and we need to know the content so we can search it so what I what we have to do is we have to basically create a simple object that just stores both the URL and and its its content so at the bottom I've got this little super simple method here this thing we called download result okay and all it does is it just calls download it download HTML but it also creates this download result and stashes it together okay so we're just going to call this I want to create a list of these things it's going to look kind of ugly in in the delegate style here but are the generics but that's okay so what we need is a list of tasks of download results right this is a good time when maybe what I might want to save our and forget how ugly it looks and then instead of doing this we're going to just say download URL okay now we're not really doing anything complicated there we're just creating an object which holds both the URL and the HTML so the next thing to do here is we're going to create a task of download result result results what we're going to do is we're going to go to all of our downloads and we're going to ask it a question we can say tasks that win any okay when any of these tasks are done we're going to store them in here maybe result is already used so let's call it um finished tasks okay so when any of these are done we're going to grab that download result and we also need to go to downloads and say remove a finished task all right and this returns a task of a task just kind of crazy so we need to it just doing a wait so we're going to wait whenever the first one is done we're going to get the result back which is one of these tasks okay and let's actually put this down here and the question we're going to ask for our loop just want to say while this count is greater than zero then we'll say finish finish task dot result dot URL and down here at the bottom want to say instead of HTML when I say dot data data is the HTML okay so instead of a waiting ship we're going to start all of them and then as they finish that's what went in II does we could say when all that would just block till they're all done but we want to process them as they get done so I want to say when any of them are done give me the first one that is done we'll take it out of our pending list process it search it and then wait again for more to come okay so if you we run this now you should see this go much faster alright so first let me clear out this window at minimum you should see them go in parallel here okay so let's go search for iPad again right see them all downloading in parallel and they're all finished okay so search again I can move around now they're all finished okay pretty cool I see there's a question if to finish to the tape same time with that logic skip the second one great question no it wouldn't it wouldn't skip it basically this thing if two of them are done it would just go through the list and return the first one that's done and then it would immediately basically the second time through that loop it wouldn't wait it would immediately turn it returned the second one rather than the first one because that second time there's only one that is finished okay so yeah now that would be fine now you might have noticed it's probably really difficult over a good a meeting but if I search and as I move around it's sort of stuck right it's not quite as smooth of an experience and the reason is this second part now is starting to dominate the processing because we're downloading so much so fast the search engine actually takes a little bit of time to go through all the HTML there's a fair amount of string processing to get through all those home pages okay and so this part which is not asynchronous is starting to really bog down the system so what we could do is write a method that does this stuff in serial art all right when the does in serial and then use convert them to tasks okay so the way we would create something like that that actually runs on a background thread as you would say tasks dot run all right task dot run is kind of like the task that we had before but it actually creates one here you can see right in the description queues specific work to run on the thread pool and return to task for that okay so that's that lets us get back and do some of this true computational processing all right I don't think we have enough time to really go into that that's kind of a little bit tricky it's not super hard or anything but let me just make a note then convert these calls to tasks that run then you get maybe we would want to say a weight test outrun then you get full parallelism okay all right so I think that does it for our demo we started out with just a purely straight single threaded application you saw that we made the UI responsive simply by adding a weight and converting a sink and a weight in two simple locations and then converting from download string to download string tasks async over in our downloader piece here right just add task async and then a weight and I think but that didn't actually add more parallelism to it because we were awaiting each result still sort of doing him in order so we had to actually change our logic ever-so-slightly to these two loops first start all the operations and then pull them out as they're done with tasks when any to actually get more parallelism out of the system okay so hopefully you guys got a good idea of the C sharp stuff that's happening the last thing I want to do let me go over here and go to the folder here I want to disassemble this thing and see how see how it looks so if we go over here when we had this is just the simple version let me throw in a something I'll just call serial and just make it a string just so we can see it in the disassembly so we know what kind of what we started with wait there okay so let's look at this in reflector which I thought I had open but I guess not so hold on a second here here we go yes and let me go ahead and close it so it will actually build okay so let's go and throw this into reflector here that it would be the websearch IX II think yeah close that up okay oh it's done at four it's not support on at four or five mm interesting well maybe I won't be able to show it to you but I can still at least tell you what's in there so if you look at what's happening inside here you if we just assemble this version right this download HTML serial it would look very very similar to what you would expect but if you throw this version into reflector which I do have two versions let me see maybe I have maybe it's the second one down here nope same problem okay well what you would see is basically it creates a state machine okay and it looks absolutely nothing like what you see written here there's a whole bunch of classes that are created and this code looks as a bunch of go twos believe it or not in it it looks really quite unusual but basically if you were to work out what is doing it says run this code down to here till you see the first two wait on the main thread the calling thread convert this to a task this download task a string really is a task already so there's not much to do to it but then convert this last bit here to actually a task dot continue with okay so that's why it's super important that you guys get that task stuff down I continue with stuff down because really that's what the compiler is doing for you all right but the real benefit is we don't have to write inside out code that you know sort of creates a bunch of delegates and passes them off and then waits for them to finish that turns out to be really hard to do you just write regular serial code and then you let the compiler compiler turn it inside out so that it can be asynchronous okay so questions comments I think I'll just leave it at that all right so like I said if you go to develop calm and you go to a web cast then you should be able to find the asynchronous programming and f45 down here all right and we should have the downloads and so on also on Twitter if you follow me on the Twitter back to beginning at M Kennedy then I'll I'll send something out today where I have links at least to the Downloads if we have the video ready all pointed that as well but you know that might take a day to get parity to get ready alright so unless there's other questions just want you to say thank you for coming and I really appreciated the time to talk about threading with you
Info
Channel: Michael Kennedy
Views: 136,364
Rating: undefined out of 5
Keywords: async, .NET, C#, .NET 4.5, Threading, Task, Parallel, Software Tutorial
Id: MCW_eJA2FeY
Channel Id: undefined
Length: 57min 10sec (3430 seconds)
Published: Mon Jul 23 2012
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.