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.
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.
Explicit disposing of CancellationTokenSource is required only when using CreateLinkedTokenSource, or if you're using the CTS' timer functionality as far as I know.
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.
Thank you for the video. This approach was extremely handy when I worked on file uploading/downloading. Implemented TaskCancellation approach with a middleware.
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
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?
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
@@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.
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.
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?
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.
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
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.
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.
i have a question. It is mandatory to pass token from controller to repository, it there any way shorter because i want to use them in repo only ? I found a suggestion that use addScope(). It will be injected to repo instead, do you have any suggestion or any solution for this ?
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?
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) ??
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?
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 ?
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?
3 года назад
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
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
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?
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.
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?
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?
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
@@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.
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
@@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/
@@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.
@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?
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
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
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?
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?
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?
@@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.
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.
s
As a C# Dev your videos are extremely helpful. Thanks for your hard work.
TaskCanceledException inherits from OperationCanceledException, so you only really need to catch the latter.
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.
Glad I scrolled down I was about to say the same thing.
Explicit disposing of CancellationTokenSource is required only when using CreateLinkedTokenSource, or if you're using the CTS' timer functionality as far as I know.
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.
Thank you for the video. This approach was extremely handy when I worked on file uploading/downloading. Implemented TaskCancellation approach with a middleware.
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
Way clearer now ! thank you so much Nick for your videos
No one has explained CancellationTokens as well as you have
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?
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
I was asking myself the same question. Would be cool to see this example done both front-end and back-end code.
@@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.
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.
This was a great explanation! Thanks a lot for the video!
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?
Correct. That was just an example when you own the CTS
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.
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
@@AvenDonn that's quite different as that's a change state request rather than a fetch current state request.
Great explanation!
Hello, thanks for sharing!!
Can we use CancellationToken to stop stored procedures execution ?
You sure can as long as you pass them in the CommandDefinition or whichever means your library allows
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.
I'd like a video in Funcs and extension methods!
hi nick. IdentityServer4 videos will be perfect if you create
Yes, pls plan a series on identity server
@Nick
Awesome video! Thanx
Great video!
C# can learn something from Kotlin - learn coroutine, and avoid checking tokens.
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 ?
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.
i have a question. It is mandatory to pass token from controller to repository, it there any way shorter because i want to use them in repo only ? I found a suggestion that use addScope(). It will be injected to repo instead, do you have any suggestion or any solution for this ?
hey Nick would it be possible to set a timeout at the Cancellation Token used as a parameter in the controller?
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?
Can you pass a cancellation token to a separate executable?
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) ??
Depending on what those method do and if they support CT you can cancel early
@@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.
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?
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 ?
Depends on the implementation. It can pop on the spot as well depending on where you passed the token
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?
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
Default Just creates a cancellation token that is never cancelled. I do not recommend using that is you really want tasks to be cancelled
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
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
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?
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.
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?
This is what I've been waiting for coz I don't know what the hell I'm using those for. 😂
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?
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
@@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.
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
@@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/
@@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.
How about browser(angular) and http client
@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?
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
@@nickchapsas thanks, got it man
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
I'm pretty sure he has already done that more or less
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?
bug of your DB driver?
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?
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?
@@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.
@@lucasdluengo Thank you very much for your reply. Will find a way to resolve this.
👍🏽
Slow down dude...