Stop wasting server resources by properly using CancellationToken in .NET

Sdílet
Vložit
  • čas přidán 19. 06. 2024
  • The first 1000 people to use the link will get a free trial of Skillshare Premium Membership: skl.sh/nickchapsas05211
    Subscribe: bit.ly/ChapsasSub
    Become a Patreon and get source code access: / nickchapsas
    This video was sponsored by Skillshare
    Hello everybody I'm Nick and in this video I am going to show you how you can properly use the CancellationToken struct in your .NET and ASP.NET Core applications in order to cancel tasks and operations early and prevent wasting valuable server resources.
    Timestamps
    ASP.NET Core implementation - 0:00
    Console app implementation - 7:10
    Don't forget to comment, like and subscribe :)
    Social Media:
    Follow me on GitHub: bit.ly/ChapsasGitHub
    Follow me on Twitter: bit.ly/ChapsasTwitter
    Connect on LinkedIn: bit.ly/ChapsasLinkedIn
    Keep coding merch: keepcoding.shop
    #cleancode #cleancoder #dotnet

Komentáře • 75

  • @nickchapsas
    @nickchapsas  Před 3 lety +11

    Thanks to Skillshare for sponsoring this video. The first 1000 people to use the link will get a free trial of Skillshare Premium Membership: skl.sh/nickchapsas05211
    This video was recorded before the release of .NET 6 which will bring the ability to reuse a CancellationTokenSource, which means that you won't have to dispose it. That being said, I did not want include that in the video since .NET 6 it is still not finalized.

  • @danspark
    @danspark Před 3 lety +28

    TaskCanceledException inherits from OperationCanceledException, so you only really need to catch the latter.

  • @Jonathan_Henderson
    @Jonathan_Henderson Před 3 lety +17

    As a C# Dev your videos are extremely helpful. Thanks for your hard work.

  • @ilyakurmaz
    @ilyakurmaz Před 3 lety

    Thank you for the video. This approach was extremely handy when I worked on file uploading/downloading. Implemented TaskCancellation approach with a middleware.

  • @thibaudgalland1524
    @thibaudgalland1524 Před 3 lety

    Way clearer now ! thank you so much Nick for your videos

  • @klightspeed
    @klightspeed Před 3 lety +13

    TaskCanceledException is a subclass of OperationCanceledException, so catching the latter will catch the former.
    On disposing of the CancellationTokenSource, it can only safely be disposed if there are no remaining cancellation tokens hanging off it, and is only required if it is not going to be cancelled. Calling Cancel on the CancellationTokenSource does the same cleanup as calling Dispose, without risking an unexpected ObjectDisposedException when something tries to use a CancellationToken linked to it.

    • @warrenbuckley3267
      @warrenbuckley3267 Před 3 lety

      Glad I scrolled down I was about to say the same thing.

    • @quain24
      @quain24 Před 3 lety

      Explicit disposing of CancellationTokenSource is required only when using CreateLinkedTokenSource, or if you're using the CTS' timer functionality as far as I know.

  • @joaonadais923
    @joaonadais923 Před 3 lety

    This was a great explanation! Thanks a lot for the video!

  • @AngusMcIntyre
    @AngusMcIntyre Před 3 lety +12

    AFAIK, we should be catching OperationCanceledException. It will be raised in some scenarios, like a call to CancellationToken.ThrowIfCancellationRequested(). OperationCanceledException is the base class, and will be emitted in all cases of cancellation.
    Inheritance: Object -> Exception -> SystemException -> OperationCanceledException
    Derived: System.Threading.Tasks.TaskCanceledException

  • @co2boi
    @co2boi Před rokem

    Good stuff, Nick. It's worth noting that, when working with Azure Functions, there are 2 potential cancellation tokens. One from the caller and one from the Host (APIM). In which case you can use a LinkedTokenSource.

  • @oleksandrkulchytskyi5970

    Great explanation!

  • @MaximGorbatyk
    @MaximGorbatyk Před 3 lety

    Awesome video! Thanx

  • @matthewtrip2124
    @matthewtrip2124 Před 3 lety +13

    No one has explained CancellationTokens as well as you have

  • @ilankhirin3678
    @ilankhirin3678 Před 3 lety

    Great video!

  • @DoorThief
    @DoorThief Před 3 lety +2

    I'd like a video in Funcs and extension methods!

  • @mirata9
    @mirata9 Před 3 lety

    I've seen technical explanations of cancellation tokens before, but no one has really put it in the context of saving resources - which is a 'super' important thing. Great vid.

  • @moab5102
    @moab5102 Před 3 lety

    Thanks Nick,
    Awesome video as always, I have a question how do you send a cancelation token from javascript,
    suppose you have a long running ajax call and a button to cancel, how do you send the token or notify the controller that the operation was cancelled.

  • @rawanabodyak8658
    @rawanabodyak8658 Před 7 měsíci

    Thank you for explaining that .
    is it worth adding the cancellation token if I'm just get small amount of data , like on user info ?

  • @marcusvmgg
    @marcusvmgg Před 2 lety

    hey Nick would it be possible to set a timeout at the Cancellation Token used as a parameter in the controller?

  • @Tsunami14
    @Tsunami14 Před 3 lety +11

    I'm a bit confused on your usage of Dispose(). The method doesn't "own" the CTS (it was passed in), so shouldn't it be left up to the owner to determine when it's done with the CTS resource and when to dispose of it?

    • @nickchapsas
      @nickchapsas  Před 3 lety +6

      Correct. That was just an example when you own the CTS

  • @Masterrunescapeer
    @Masterrunescapeer Před 2 lety

    Interesting video, in our case we ended up not implementing it after seeing that most immediately made the request again after cancellation as it was usually an accidental navigate away and all requests end up cached in Redis anyways, there's more than enough cache that DB doesn't get hit that hard, DB is way over-provisioned for when reports are generated.

    • @asedtf
      @asedtf Před 2 lety

      That makes sense in your case, but not all cases are like this.
      For example, I work on digital printing presses, physical machines. A cancellation might be the operator cancelling a "get ready" operation which involves a lot of moving parts, liquids, and electricity.
      We very much don't want to finish the "get ready" anyway, especially if the "get ready" is being aborted because they remembered they need to replace a part for example.
      So it's important to be mindful of what cancellation means and what saving resources means.
      I think both our notions are important. Don't prematurely optimize and try to save on resources you don't need to, and don't assume there's no need for cancellation

    • @Masterrunescapeer
      @Masterrunescapeer Před 2 lety

      @@asedtf that's quite different as that's a change state request rather than a fetch current state request.

  • @spuriustadius5034
    @spuriustadius5034 Před 3 lety +12

    Thanks Nick!
    In the Postman example, you hit a "cancel" button which somehow simulates closing the browser, right? What if you wanted to have a "cancel" button on your webpage? How would you trigger the cancellation in a web app without closing the browser? In other words, if you wanted to provide a way for a web user to cancel a long calculation they had already started, how would you do that? It's clear how to do it in a console app, but in a web app you have to worry about which httpcontext, right?

    • @nickchapsas
      @nickchapsas  Před 3 lety +3

      Yeah the way I imagine it (and I haven't tested it) is that you would keep track of the request in the pipeline and have a way to trigger the CancellationToken in some manual way

    • @iurynunesamicussi5147
      @iurynunesamicussi5147 Před 3 lety +3

      I was asking myself the same question. Would be cool to see this example done both front-end and back-end code.

    • @ArgeKumadan
      @ArgeKumadan Před 3 lety +3

      @@nickchapsas i've tested it before. For each request that is aborted browser tries to stop the socket connection gracefully. But in case of it can't do it and if somehow connection closes the framework passes that token. This applies for both scenario.

    • @maheshk2451
      @maheshk2451 Před 3 lety +3

      One way to cancel from frontend is using axios, i used it in my react application where you can cancel your requests any time. Type ahead search is a good example.

  • @raminquliyev2268
    @raminquliyev2268 Před 3 lety +21

    hi nick. IdentityServer4 videos will be perfect if you create

  • @darklen14
    @darklen14 Před rokem

    What about an API application. If the call is taking a long time. Do you set up cancellation token in the app connecting to the api service and then pass it to that api service? Or when the app is running and the user closes the page and cancellation token is only set up in the api endpoint it will suffice?

  • @kunaldedhia5502
    @kunaldedhia5502 Před 2 lety

    Is it correct to use cancellation token for "http put", "http patch", "http post", "http delete"?
    Bssically i would like to know what all http methods can implement cancellation token in web api?

  • @shekharkumar-il1jz
    @shekharkumar-il1jz Před 2 lety

    So I have a situation where I found that an API keep running due to incorrect implementation of do while loop. Can this canclellationtoken will work in that situation also. Like I can set timeout for cancliation token for 5 seconds and it automatically stop/kill those threads used by it?

  • @santhoshn3766
    @santhoshn3766 Před 3 lety +1

    Hello, thanks for sharing!!
    Can we use CancellationToken to stop stored procedures execution ?

    • @nickchapsas
      @nickchapsas  Před 3 lety +1

      You sure can as long as you pass them in the CommandDefinition or whichever means your library allows

  •  Před 3 lety

    Great explaination. I'm missing the part where a method is declared with a default cancelation token. eg: public void DoAsync(CancelationToken cancel = default).
    Where is the default CancelationTokenSource

    • @arthursoares610
      @arthursoares610 Před 2 lety

      Default Just creates a cancellation token that is never cancelled. I do not recommend using that is you really want tasks to be cancelled

  • @thethomasproject
    @thethomasproject Před 3 lety

    Nick, I do have a question for you. What's the best method to handle a cancellation token when the request was a database write that could be more than one write to complete the transaction? Seems once this gets started, cancelling it could put the database into a bad way. Your thoughts?

    • @nickchapsas
      @nickchapsas  Před 3 lety

      If you pass the CT in a transaction execution CommandDefinition the execution will be cancelled and the transaction will never be commited and get rolled back instead.

  • @jinalpatel9154
    @jinalpatel9154 Před 3 lety

    For the example let's assume that inside while loop you wait for some external event and then you cancel token source outside so I think in this case it still wait for that external event to receive then it process get cancel. Right ?

    • @nickchapsas
      @nickchapsas  Před 3 lety

      Depends on the implementation. It can pop on the spot as well depending on where you passed the token

  • @nayanchoudhary4353
    @nayanchoudhary4353 Před 2 lety

    C# can learn something from Kotlin - learn coroutine, and avoid checking tokens.

  • @ArgeKumadan
    @ArgeKumadan Před 3 lety

    Good explanation, thanx. But,
    What if we don't have a some kind of loop? we can't use while (!cancelled)
    Should we just put 1 of 2-3 lines if(!cancelled) ?
    Let's say i have 10 methods call in 1 method? should i just wrap those calls as if(!cancelled) ??

    • @nickchapsas
      @nickchapsas  Před 3 lety

      Depending on what those method do and if they support CT you can cancel early

    • @ArgeKumadan
      @ArgeKumadan Před 3 lety

      @@nickchapsas no, let's say it's a CPU bound operation and not a task. Should we wrap them inside of a Task.Run?
      Thanks for the reply by the way.

  • @sebastianp.r.gingter1936

    Hi Nick, I tried to reproduce that, but it seems I can't make it work. I cancel the request, but the first DB query isn't cancelled - it simply runs until it finishes. So when I cancel after a second, the cancellation is still detected only after the first query is finished, like 6 seconds later. So in fact it doesn't matter if the cancellation token is passed to the CommandDefinition or not: the actual DB query won't be aborted. What did you do to actually cancel the currently running Db query?

    • @flybyw
      @flybyw Před rokem

      bug of your DB driver?

  • @diegoronkkomaki6858
    @diegoronkkomaki6858 Před 3 lety

    Going to implement the cancellation token in my .NET Core web api controllers now.
    Question though. How should I implement the CancellationTokenSource in my client applications (Blazor WASM in my case)? Do I register a singleton CTS in the DI container and inject that into my blazor components/pages or what is the best practice approach?

    • @nickchapsas
      @nickchapsas  Před 3 lety

      It’s very likely that Blazor has built in CT support. I would check that first. If not then you would need to register it as scoped. That being said you might wanna leave the cancelling on the server only since the client can make many actions anyway

    • @diegoronkkomaki6858
      @diegoronkkomaki6858 Před 3 lety

      @@nickchapsas Oh, right.. wait. I might still be a bit confused. If, for example, the controller's GET method takes a cancellation token as a parameter, is the token then provided by the client in the GET request? Surely not, since you'd have to send the CT object as a serialized object in the request body? What then actually triggers the CT? I was somehow thinking there'd be a "Cancel" button in the Blazor web site which would cancel the long running api call (pretty much like pressing C in your console application example) but now Im starting to think that's not how it's supposed to work in web api's or even possible.

    • @nickchapsas
      @nickchapsas  Před 3 lety

      I’m gonna be honest, I don’t know exactly the technical trigger for the cancelling of the request but client and server are completely separate. I would have to take a lot at asp.net core’s source code

    • @diegoronkkomaki6858
      @diegoronkkomaki6858 Před 3 lety

      @@nickchapsas reading a bit about this, it seems that from the clients (browser) point of view, cancelling is regarded as refreshing the web page or pressing the stop button while the page is loading (waiting for data from the API server). Somehow, the browser and web api handles these under the hood and triggers the cancellationtoken.
      So the client side code actually doesn't have to implement any kind of CTS to pass tokens to the web api.
      I initially thought (mistakenly) that it would somehow be possible to create a "Cancel" button on a web page that would cancel any previous calls to a web api. I have worked with cancellation tokens in my desktop apps but never really thought about how they would work in web apps.
      The links below cleared this up for me. And thank you Nick for taking time to reply.
      stackoverflow.com/questions/19010856/should-we-use-cancellationtoken-with-mvc-web-api-controllers
      andrewlock.net/using-cancellationtokens-in-asp-net-core-mvc-controllers/

    • @ilh86
      @ilh86 Před 3 lety +1

      @@diegoronkkomaki6858 The client and server side are separate but work together in a sense. You can pass a cancellation token to HttpClient methods which will cancel the client side of things and the server side should then recognise that the client isn't listening anymore and cancel it's own token that Nick shows in the video. In Blazor I create a CTS in the component and pass the token to the HttpClient call. In the dispose method of the component I call cancel on the CTS so that if the user navigates away from the component (which disposes it) before the request comes back it is cancelled but you could hook it up to a button click or any other user interaction you want to cancel it. If you do it as a singleton in DI then you will only be able to use it once as once it's cancelled it's essentially finished with.

  • @amjadhossain7114
    @amjadhossain7114 Před 3 lety

    @Nick can you show how to use cancellation token with .NET core Web API and MediatR. Or a little bit insight? MediatR handler method has a cancellation token parameter but how to pass controller method cancellation token to the handler?

    • @nickchapsas
      @nickchapsas  Před 3 lety +1

      Depends on how the flow begins. If it’s in a web api context then you can get it from the controller. Just add it as a parameter in the action and it will magically be there. After that just pass it down

    • @amjadhossain7114
      @amjadhossain7114 Před 3 lety

      @@nickchapsas thanks, got it man

  • @yoshkoneski
    @yoshkoneski Před 3 lety +4

    Hi Nick, can u make a playlist videos that build start App complete with management menus, jwt api, authentication & authorization, additional userClaim for example: userCompany, userId,UserFullName, userRoles(multiple role per User)
    Registration & login auth using google
    Thanks

  • @clashclan4739
    @clashclan4739 Před rokem

    How about browser(angular) and http client

  • @scott98390
    @scott98390 Před 2 lety

    Should you really be Disposing the CancellationTokenSource? If it was passed in, it was created somewhere else, and might need to be used further. I agree that if you create it you should dispose of it, but can you explain disposing in this instance? I feel like you should wrap the creation in Main() in a using{} block, rather than dispose in ExampleWithLoop

    • @nickchapsas
      @nickchapsas  Před 2 lety

      If you control the CT flow end to end then yeah you should. If you use a token that you didn’t create then no

  • @Srhyle
    @Srhyle Před 3 lety

    This is what I've been waiting for coz I don't know what the hell I'm using those for. 😂

  • @clearlyunwell
    @clearlyunwell Před 3 lety

    👍🏽

  • @lucasdluengo
    @lucasdluengo Před 3 lety

    I tried this in an Azure function HttpTrigger, using the req.HttpContext.RequestAborted token... but it never gets triggered. Anyone knows why that may be so?

    • @nirushdeveloper5148
      @nirushdeveloper5148 Před 2 lety

      Hi Lucas,
      Were u able to get it done? For me it triggers to the azure function. But canceled exception is not caught in the calling method unless we use a loop. Any ideas?

    • @lucasdluengo
      @lucasdluengo Před 2 lety +2

      @@nirushdeveloper5148 Yes, but it was not a problem with azure. it was a proxy for my SPA that was not propagating the cancellation. And answering your question, yes. The ThrowIfCancellationRequested only is evaluated the moment you call the instruction. Is not something that keeps checking and throws an exception if at any point you cancel the request.... disappointning, but reasonable.

    • @nirushdeveloper5148
      @nirushdeveloper5148 Před 2 lety

      @@lucasdluengo Thank you very much for your reply. Will find a way to resolve this.

  • @mikedensem
    @mikedensem Před 8 měsíci

    Slow down dude...

  • @gabrielcostin8867
    @gabrielcostin8867 Před 3 lety

    I have a question here regarding to properly using CancellationTokens. So I tried on my own using it but when trying to call the API endpoint via ajax call the cancellationToken is automatically triggered after like 1 minute, is there any way to stop doing this and actually wait for the response?