The series so far:

  1. The Unconventional Guide to Introduction to Thread
  2. Why Do People Think Dedicated CLR Threads is a Good Idea?
  3. How Not Knowing Thread Members and Execution State Makes You a Rookie
  4. Doing Thread Scheduling and Priority the Right Way
  5. How to Start Using CLR's Thread Pool
  6. What Wikipedia Can't Tell You About Thread Execution Contexts
  7. The Insider's Guide to Cooperative Cancellation and Timeout

What is a Cooperative pattern?

Cooperative is a Standard Pattern for Cancellation Operations meaning the operation we wanted to cancel explicitly supports cancelling. The Cancellation is cooperative, i.e. not forced on the listener.

The general pattern for implementing the cooperative cancellation model is:

  1. Instantiate a CancellationTokenSource object, which manages and sends the cancellation notification to the individual cancellation tokens.
    This model is based on a lightweight object called a cancellation token.

  2. Pass the token returned by the CancellationTokenSource.Token property to each task or thread that listens for cancellation.
    The object that invokes one or more cancelable operations, for example by creating new threads or tasks, passes the token to each operation. Individual operations can, in turn, pass copies of the token to other operations.

  3. Provide a mechanism for each task or thread to respond to cancellation.
    The object that created the token can use it to request that the operations stop what they are doing, at some later time.

  4. Call the CancellationTokenSource.Cancel method to provide notification of cancellation.
    Only the requesting object can issue the cancellation request, and each listener is responsible for noticing the request and responding to it in an appropriate and timely manner.

Important
The CancellationTokenSource class implements the IDisposable interface. You should be sure to call the CancellationTokenSource.Dispose method when you have finished using the cancellation token source to free any unmanaged resources it holds.

Type name Description
CancellationTokenSource Object that creates a cancellation token, and also issues the cancellation request for all copies of that token.
CancellationToken Lightweight value type passed to one or more listeners, typically as a method parameter. Listeners monitor the value of the IsCancellationRequested property of the token by polling, callback, or wait handle.
OperationCanceledException Overloads of this exception's constructor accept a CancellationToken as a parameter. Listeners can optionally throw this exception to verify the source of the cancellation and notify others that it has responded to a cancellation request.

Please refer the below code where we followed the above steps for Cooperative Cancellation. Please find the running code at link

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
          // 1. Create the token source.
          CancellationTokenSource cts = new CancellationTokenSource();

          // 2. Pass the token to the cancelable operation.
          ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomeWork), cts.Token);
          Thread.Sleep(2500);

          // 4. Request cancellation.
          cts.Cancel();
          Console.WriteLine("Cancellation set in token source...");
          Thread.Sleep(2500);
          // Cancellation should have happened, so call Dispose.
          cts.Dispose();
        }
        
       // 3. Thread 2: The listener
       static void DoSomeWork(object obj)
       {
          CancellationToken token = (CancellationToken)obj;

          for (int i = 0; i < 100000; i++) {
             if (token.IsCancellationRequested)
             {
                Console.WriteLine("In iteration {0}, cancellation has been requested...",
                                  i + 1);
                // Perform cleanup if necessary.
                //...
                // Terminate the operation.
               break;
             }
             // Simulate some work.
             Thread.SpinWait(500000);
          }
       }
    }
    // The example displays output like the following:
    //       Cancellation set in token source...
    //       In iteration 1430, cancellation has been requested...
}

How to: Listen for Multiple Cancellation Requests

CreateLinkedTokenSource method is used to join two tokens into one token. This enables the token to be passed to methods that take just one cancellation token as an argument. You can create a composite token that consists of several other tokens. The Task will then be cancelled if any of the underlying tokens has been cancelled. Here’s how you create a composite token:

CancellationTokenSource cancellationTokenSourceOne = new CancellationTokenSource();
CancellationTokenSource cancellationTokenSourceTwo = new CancellationTokenSource();
CancellationTokenSource cancellationTokenSourceThree = new CancellationTokenSource();
CancellationTokenSource compositeTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationTokenSourceOne.Token, cancellationTokenSourceTwo.Token, cancellationTokenSourceThree.Token);

Use this composite in the constructor of the Task and you can cancel the task by calling the Cancel() method of any of the tokens in the composite.

Note:
Note that this method only signals the wish to cancel a task. .NET will not actively interrupt the task, you’ll have to monitor the status through the IsCancellationRequested property. It is your responsibility to stop the task. In this example we throw an OperationCanceledException which is a must in order to correctly acknowledge the cancellation. If you forget this step then the task status will not be set correctly. Once the task has been requested the stop it cannot be restarted.

References:

Cancellation in Managed Threads
Multiple Cancellation Requests
Cancelling a Task with a composite cancellation token