Search code examples
c#.nettask.net-standardcancellation

Immediate Task Cancellation


I have a question regarding task cancelling using cancellationToken and cancellationTokenSource:

The usual way is as follows:

var cts = new CancellationTokenSource();
var t = Task.Run(() => {    
while(true)
  {
    if (!cts.IsCancellationRequested)   
     {  //do stuff }
  }
}, cts.Token);

So, the while loop keeps going until the token is requested. Today, while studying the Cancel() method I found that you can use the Register() Method in order to define other code to run when the token is requested, so I was wondering, what if one wrote something like this:

var cts = new CancellationTokenSouce();
token=cts.Token;
token.Register(
() => {
//do something to manage the cancel call
return;
};
) 
var t = Task.Run(() => {
//do stuff 
}, cts.Token);

By doing so, the task associated with the CancellationToken would immediately stop executing, instead of having to complete the current for iteration like it would in the usual implementation. My question is: is this the right way to immediately stop a Task or there is a better way?


Solution

  • Register doesn't cause a task stop executing it's just a notification that a cancellation has been requested. The main purpose of Register is to have ability to cancel asynchronous operations which don't support CancellationToken but have their own mechanism of cancellation or can be cancelled indirectly (by closing a socket for example). There are also some tricks described by Stephen Toub here of how to cancel non-cancelable tasks with Register. If you however control the execution of a task which should be cancelled it's your responsibility to supply a mechanism to cancel execution. There is no the best approach how to cancel any task - some tasks can be cancelled immediately (you can use ThrowIfCancellationRequested), some may require some additional handling (you need to check that cancellation is requested, do something and then throw the exception).