What is the use of passing CancellationToken to Task Class constructor?

Prabhu Murthy picture Prabhu Murthy · Jun 1, 2012 · Viewed 20.8k times · Source

Here is a sample code that creates a new task that simulates a long running process. There is nothing much on the task as such and purely focuses on the cancelling features. I am using cancellation token to cancel the task and the code works fine for me.

CancellationTokenSource CTS = new CancellationTokenSource();

Task<Boolean> PTask = new Task<Boolean>(() => 
{
   while (true)
   {
       if (!CTS.Token.IsCancellationRequested)
       {
          Thread.Sleep(5000);
       }
       else { Console.WriteLine("Thread Cancelled");break; }
   }
   return true;

}, CTS.Token, TaskCreationOptions.None);

PTask.Start();
Console.WriteLine("Hit Enter to cancel the Secondary thread you have started");
Console.ReadLine();
CTS.Cancel();
System.Console.WriteLine(PTask.Result);

But one thing that I could not understand is the token parameter (CTS.Token) that is being passed on to the Task constructor. What is the actual use of passing the parameter, when I can actually cancel the task even without passing token to the constructor.

Down below is a slightly modified version that works without the token parameter.

CancellationTokenSource CTS = new CancellationTokenSource();
Task<Boolean> PTask = new Task<Boolean>(() => 
{
   while (true)
   {
       if (!CTS.Token.IsCancellationRequested)
       {
           Thread.Sleep(5000);
       }
       else
       {
           Console.WriteLine("Thread Cancelled");
           break;
       }
};

Answer

daryal picture daryal · Jun 1, 2012

UPDATE: The following msdn question describes the reason:

Passing a token into StartNew associates the token with the Task. This has two primary benefits:

  1. If the token has cancellation requested prior to the Task starting to execute, the Task won't execute. Rather than transitioning to Running, it'll immediately transition to Canceled. This avoids the costs of running the task if it would just be canceled while running anyway.

  2. If the body of the task is also monitoring the cancellation token and throws an OperationCanceledException containing that token (which is what ThrowIfCancellationRequested does), then when the task sees that OCE, it checks whether the OCE's token matches the Task's token. If it does, that exception is viewed as an acknowledgement of cooperative cancellation and the Task transitions to the Canceled state (rather than the Faulted state).