Be a pro! Use cancellation tokens in Blazor Server

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey there and welcome back to the code wrinkles channel for a brand new video on blazer server and in this one i guess we'll talk about a very very nice topic and that would be how to develop blazer server applications like pros by using cancellation tokens now this might sound a little bit weird to you but really in each application that you develop no matter if it is a blazer application or a regular.net core web api or an asp.net core mvc application using cancellation tokens is very very important now the very basic concept about these cancellation tokens is that when you have long running tasks that needs to be performed like for instance calling the database or making an http call we have very often the use case for instance that somebody makes a call accesses a page then if that actually takes too long the user just navigates away now the problem is that if you don't use these cancellation tokens even if the user navigates away from this specific page the operation will still run till the end and this is how we actually waste a lot of resources so this means that we would need a mechanism to actually take action and when the user cancels the request in any way if it navigates away or by any other mean we should just also be able to cancel the operation and this is how we and we achieve this in the dot-net world i would say by using this concept of cancellation tokens that include an information whether the cancellation for a certain task was required or not and the cool thing is that i would say pretty much all dot net libraries that uh expose async apis like async methods like for instance edited framework core or the http client all also implements method overloads that take in and cancel a cancellation token so you can just provide them the cancellation token and they will make sure that they will abort the operation when the cancellation is required now this was very easy to do and straightforward in asp.net core because what asp.net core does in regular mvc based applications is that when a request comes in it actually creates a cancellation token source and it passes in that cancellation token that was generated from that source to the controller action that was executed and this means that we can directly take the cancellation token from there and pass it down the stream to all other libraries and methods that perform some async stuff now this we don't have by default in blazer server so this means that we as developers for now we have to take care about this by ourselves and before we actually show how we implement this i really want to also visualize the use case for that so i have here a blazer server application that we have already used for some videos on this channel on how to use entity framework core and blazer server the right way using the db context factory and then also how we can do this while we have a more traditional approach with a repository and services or a more modern approach with command handlers or query handlers and actually that's what we are using here in this component because we have a query and we use the mediator to just send that query and it will execute the handle method and we'll get the data for us now let me run this application because as i said this is something that i would like to also visualize before we really get into how we implement this and i will also change here this view to only see things in the console that we generate from our application and i will bring the application right now on the other screen now what we have here and before i click on anything i just briefly want to explain that we have this fetch data component and this all forecast component these are two different components however they use the exact same query and and query handler to get the exact same data which is a list of weather forecasts and we actually really get them from the database still in the handler i have added some things that we will take a look just in a few seconds but right now i want to go with you over this scenario so i am a user i am clicking here on this fetch data component and i see that hey that takes a long time i really get bored so let me navigate to this other component now of course this component with all will also have to wait for i guess 10 seconds and we'll see exactly why and after 10 seconds it will display my data which is cool now let us take a look at what we actually have here in in this console so what what we have written here and for that let me also get to this get all forecasts query where let's walk through what we do here we just get all the forecasts from the database so that's okay but then we want to simulate that this process takes very very long and we have this task delay of 10 000 milliseconds which is actually 10 seconds and afterwards we right here waited for 10 seconds in the console now let's take a look at this again so we have here waited for 10 seconds two times in the console now remember what we have done in the applications as users so first we have clicked on this fetch data the component was initialized data was loading so we were waiting for these 10 seconds but then we got bored and we clicked on a different component and still the component the the other component used the exact same uh handler so that's why we actually see that we have this waited for 10 seconds two times now of course we didn't really wait 20 seconds because these are with the weight so while we were awaiting the first one some things were already started on the second one and things like that so they were not fully 20 seconds still from the timeline that we have actually navigated the way to a different component this first task that actually started was wasting resources because we as users we have canceled it we didn't want to actually look at that component anymore we have navigated away and still even if we have navigated away in back end or what happened here in the back end is that we still waited for 10 seconds to complete before actually passing uh to the next one so that's a very very important thing and that's actually the behavior that we want to resolve to not waste resources so when a user navigates away from a blazer component the tasks the ongoing tasks should also be cancelled we we shouldn't wait this this operations to complete so as said this unfortunately is not by default or we don't have a cancellation token by default in blazer server but it's actually very very easy to implement this by ourselves now the one thing that we need to do here is we have here this fetch data component which is the first component that that we have clicked actually so what we want to do here is we will do something similar to what asp.encore does in an mvc based application so instead of just relying on the framework to get the cancellation token here we will simply go on and create one by ourselves so we will have private we have to also type it correctly and it would be cancellation what we need is a cancellation token source and let's call this source and that would be equal to new cancellation token source so we have right now created a new cancellation token source so this means that each time this component gets initialized we will also initialize a new cancellation token source and that's actually very very nice because what we can do here in this case we can go here on in this own initialized async and what we can do here is this mediator we have already seen in in the handle method that it accepts a cancellation token if we provide one so we can just come on or come here and say that we want to provide source dot token and this will send the token further down the line to our command handler sorry query handler in this case so let's go back to the handler right now we also we know that we pass in the cancellation token and the cool thing that we can do is actually that in this task delay we can even pass in the cancellation token okay and this will ensure that this task will be immediately stopped when the cancellation is required or when the operation was actually cancelled by the user in some way and that's actually all the things that we need to do we just need to create that cancellation token source and then make sure that we pass it to the mediator to continue to work and of course the same way we could pass into our repository and the repository could pass it to the db context and theoretically this one should also accept for instance one with cancellation token you see as said most of the apis that use async code or that end here with async they have implementations overloads for handling also or working with cancellation tokens so we can even pass it here now the only thing that it's still that we still need to resolve is that okay how do we make sure that when a user navigates away from one component that we actually really trigger a task cancellation so that all the the downstream operations that that might be in progress know that the that those operations needs to be cancelled and for that we will go back here to our fetch data component and it's actually very very easy because what happens with components when we navigate away well it means that the old component is not needed anymore and therefore the old component is simply disposed now what this means is that we could simply also implement i disposable here and let's go here and say implement i disposable now they should do it and of course we need to also implement this method so let's go here down the line uh and this is a public one and so let's put it directly under this one so it would be public bull dispose and there is where we need to do so it means that when a component gets disposed we want actually to go to our source and say cancel so we just want to cancel all or to actually say that the cancellation was required and then of course we can even dispose the resource so that is actually uh what we need to do okay what is the problem here okay not all code but okay but it's void sorry public void so yeah of course this this dispose method should be of course void and now everything should be fine we have implemented the idisposable interface so let me walk you through what i would expect to happen right now so when we run the application once again when we click here on fetch data we should have a new cancellation token source and when we send everything to the mediator we would pass in a cancellation token and while we wait we will navigate away from that component to another component and that would trigger this dispose method that would actually cancel the token and all the operations that actually rely on the token will be notified we'll see that the operation or or that the cancellation was requested and they will really stop to execute that method so in the end what i would expect here is that in the console here instead of having waited for 10 seconds two times we would have waited for 10 seconds only one time because the first one we will did the operation will be cancelled as soon as we dispose this component so let's run the application once again and see if this is really the case this was a very very brief explanation of what i would have expected or what i would expect cool so we have everything running again we have this one here so let me just bring also the page back here on this other screen and let's do this once again so we click on fetch data we see that hey it takes a little bit longer i'm good i'm bored about that so let's click on the other component and we click here on all forecasts so if we go back to our visual studio we see that we have waited for 10 seconds only one time and that's actually a very very nice now let's try to maybe go here and once again maybe just go on home maybe just do a refresh here to to have everything fresh and for instance right now let's click on fetch data and then let's click on counter and we can already use this counter and if we go back to visual studio we can wait as long as we want because we won't see any message anymore we waited for 10 seconds that's because we have clicked on fetch data we have waited for a few time then we have navigated away so we we have cancelled effectively that component we didn't want it anymore and this information was then passed down the line to all tasks that actually were performing some work and all the operations were cancelled and that's actually it about how to use cancellation tokens in blazer server applications to make sure that you really don't waste any resources and cancel all the operations the moment that the cancellation is requested of course depending on your different scenarios or use cases you might work with different type of cancellation tokens you might have a source for disposing that that will trigger when something gets disposed if you don't want to wait for instance if you make http calls that take too long and to just want to to set some timeouts you can just create maybe a new cancellation token source with a timeout uh in itself so the task or or the cancellation will in that case be required as soon as we actually hit the threshold that we have specified in the time span so there might be some different other scenarios but this would be i assume one of the most common ones where when you work with data in your components just create for yourself a cancellation token source and make sure that you pass in the token to all the async methods that you call down the line and of course also make sure that you cancel the task and dispose the source when uh that is not needed anymore because it could be that you want you don't want to wait for the dispose maybe you want to just wait here for three seconds if you don't get the data you just want to cancel everything and i don't know maybe show a timeout error or something like that so that would also be totally fine and yet in that case we would actually have to implement here a way to to actually send a request for for cancellation so once again scenarios might become a little bit more trickier but if you have this common idea about how this cancellation token source works in blazer server and how you can use it then i would assume you are on a very very good track to really write performant applications that don't waste resources very very important if you enjoyed this video please hit the thumbs up button subscribe of course if you didn't already for awesome new content that we try to deliver as fast or as soon as possible we are doing a bunch of stuff like videos we are doing a lot of live coding sessions and have a lot of cool discussions actually during those uh live coding sessions so you are also welcome there if you think that other people might benefit from that don't uh don't hesitate and feel free to share this content with with your peers with your friends on your social networks networks wherever you might see fit and that would be highly appreciated and last but not least if you have any questions or if you just want to get a discussion going on something or if you have maybe better ideas than what i have presented here in this video don't be shy and use the comments section of this video it would be awesome if you could write something there and i will promise that i will look into that and i will also respond to your messages this being said once again thank you very much for watching and until the next time i wish you the very best
Info
Channel: Codewrinkles
Views: 132
Rating: undefined out of 5
Keywords:
Id: 97gGYgZ8xU0
Channel Id: undefined
Length: 17min 56sec (1076 seconds)
Published: Wed Dec 15 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.