A enables cooperative cancellation between threads, thread pool work items, or objects. In this article, I would like to discuss the mechanism which is applicable for Task objects. CancellationToken Task When you run a task in C#, it may take a while to execute it. In some cases, you would like to cancel such a long operation. There could be a number of reasons: operation timeout, exceeding resource limits, etc. The Algorithm Create an object of the type that signals cancellation to the token. CancellationTokenSource Pass the property as a token object to the task. CancellationTokenSource.Token Define the behavior of the task for terminating the operation according to the cancellation signal. Call method which sets property to a value. That means that method does not cancel the operation itself. It just changes the property value. We as developers have to define cancellation logic by ourselves. CancellationTokenSource.Cancel() CancellationToken.IsCancellationRequested true Cancel() IsCancellationRequested type implements the interface and has to be released when a task is completed. It could be done manually by calling method or vi construction. CancellationTokenSource IDisposable Dispose() using Sample code to demonstrate the algorithm above: // initialize cancellation objects CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); CancellationToken token = cancelTokenSource.Token; // execute a parallel operation Task task = new Task(() => { some_operations }, token); task.Start(); // cancel the operation cancelTokenSource.Cancel(); // release resources cancelTokenSource.Dispose(); Let’s discuss in the detail. There are two ways how to define the logic of task terminating using a cancellation token: step #3 Use operator to exit the task execution. In this case, the state of the task will be . return TaskStatus.RunToCompletion Throw type exception via method call. In this case, the state of the task will be . OperationCanceledException ThrowIfCancellationRequested() TaskStatus.Canceled Complete Task via Operator return public static void Main(string[] args) { CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); CancellationToken token = cancelTokenSource.Token; Task task = new Task(() => { for (int i = 1; i < 100; i++) { if (token.IsCancellationRequested) { Console.WriteLine("Operation is canceled"); return; } Console.WriteLine($"Count is equal to '{i}'"); //add some timeout to emulate real-life execution Thread.Sleep(10); } }, token); task.Start(); // add some timeout to emulate real-life execution Thread.Sleep(100); // cancel the parallel operation cancelTokenSource.Cancel(); // wait till the operation is completed task.Wait(); // check the operation status Console.WriteLine($"Task Status is equal to '{ task.Status }'"); // release resources cancelTokenSource.Dispose(); } The result of this execution is following: Count is equal to '1' Count is equal to '2' Count is equal to '3' Count is equal to '4' Count is equal to '5' Operation is canceled Task Status is equal to 'RanToCompletion' Complete Task via Method Call ThrowIfCancellationRequested() public static void Main(string[] args) { CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); CancellationToken token = cancelTokenSource.Token; Task task = new Task(() => { for (int i = 1; i < 100; i++) { if (token.IsCancellationRequested) token.ThrowIfCancellationRequested(); Console.WriteLine($"Count is equal to '{i}'"); //add some timeout to emulate real-life execution Thread.Sleep(10); } }, token); try { task.Start(); // add some timeout to emulate real-life execution Thread.Sleep(100); // cancel the parallel operation cancelTokenSource.Cancel(); // wait till the operation is completed task.Wait(); } catch (AggregateException ae) { foreach (Exception e in ae.InnerExceptions) { if (e is TaskCanceledException) Console.WriteLine("Operation is canceled"); else Console.WriteLine(e.Message); } } finally { // release resources cancelTokenSource.Dispose(); } // check the operation status Console.WriteLine($"Task Status is equal to '{ task.Status }'"); } The result of this execution is following: Count is equal to '1' Count is equal to '2' Count is equal to '3' Count is equal to '4' Count is equal to '5' Operation is canceled Task Status is equal to 'Canceled' The thrown exception will appear as an of the . If the task was cancelled via method call the exception will be the type of . The code checks for this type for proper handling, otherwise, handle another exception reason. InnerException AggregateException ThrowIfCancellationRequested() TaskCanceledException The exception will be thrown only in case when or method is called for the task. Otherwise, no exception is thrown, just is set. Wait() WaitAll() TaskStatus.Canceled Register Operation Cancellation Handler Another way to define the logic of the task cancellation is to use method. It registers an delegate that will be called when the is cancelled. Register() Action CancellationToken public static void Main(string[] args) { CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); CancellationToken token = cancelTokenSource.Token; Task task = new Task(() => { int i = 1; token.Register(() => { Console.WriteLine("Operation is canceled"); i = 100; Console.WriteLine($"Count is equal to '{i}'"); }); for (; i < 100; i++) { Console.WriteLine($"Count is equal to '{i}'"); //add some timeout to emulate real-life execution Thread.Sleep(10); } }, token); task.Start(); // add some timeout to emulate real-life execution Thread.Sleep(100); // cancel the parallel operation cancelTokenSource.Cancel(); // wait till the operation is completed task.Wait(); // check the operation status Console.WriteLine($"Task Status is equal to '{ task.Status }'"); // release resources cancelTokenSource.Dispose(); } The result of this execution is following: Count is equal to '1' Count is equal to '2' Count is equal to '3' Count is equal to '4' Count is equal to '5' Operation is canceled Count is equal to '100' Task Status is equal to 'RanToCompletion' In this code then the method is called the delegate defined in the method is triggered. In this example, the code sets variable to value which causes the end of the task execution. cancelTokenSource.Cancel() token.Register() i 100 If the code does not wait for the operation competition the task status will be . If or method is called the task status will be . TaskStatus.Running Wait() WaitAll() TaskStatus.RanToCompletion Summary: Using a Cancellation Token Cancellation of the task is very important to optimize the logic of your application. You may need to cancel the task for many reasons: operation timeout, exceeding resource limits, etc. You always need to handle the cancellation logic by yourself. You can do it via operator or via method call. return ThrowIfCancellationRequested()