SoFunction
Updated on 2025-04-08

.Net uses Cancellation Framework to cancel parallel tasks

In .net 4.0, a new class CancellationToken was introduced. This class basically integrates various commonly used cancellation methods and is very useful in concurrent tasks.

Cancel in synchronization mode:

A more common thing that requires the cancellation function is some time-consuming segmentation operations: such as video conversion, network download, etc. The cancellation mechanism under this method is as follows:

  • Create a mark bit indicating whether the operation has been cancelled

  • After the UI thread gets the cancel event, sets the mark to true.

  • In the time-consuming operation thread, the mark bit is checked after a short operation is not performed, and if it is true, it will automatically exit.

How to use it is as follows:

    EventHandler externalEvent;
    void Example1()
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        externalEvent +=
         (sender, obj) => { (); }; //wire up an external requester 
        try
        {
            int val = LongRunningFunc();
        }
        catch (OperationCanceledException)
        {
            //cleanup after cancellation if required... 
        }
    }

    private static int LongRunningFunc(CancellationToken token)
    {
        int total = 0;
        for (int i = 0; i < 1000; i++)
        {
            for (int j = 0; j < 1000; j++)
            {
                total++;
            }
            if ()
            { // observe cancellation 
                throw new OperationCanceledException(token); // acknowledge cancellation 
            }
        }
        return total;
    }

Cancel in asynchronous mode

Another common method is that in some asynchronous operations, they often cannot be released actively, and they can only wait for the asynchronous operation callback to operate the result. The general cancellation method is as follows:

  • The task thread registers the callback function completed by the asynchronous operation and starts the asynchronous operation.

  • The UI thread accepts the cancel command, sets the cancel flag bit, and actively executes the callback function.

  • The callback function determines whether the task has been completed or cancelled by canceling the mark bit, and performs related destructuring operations.

How to use it is as follows:

    void BlockingOperation(CancellationToken token)
    {
        ManualResetEvent mre = new ManualResetEvent(false);
        //register a callback that will set the MRE 
        CancellationTokenRegistration registration =
         (() => ());
        using (registration)
        {
            ();
            if () //did cancellation wake us? 
                throw new OperationCanceledException(token);
        } //dispose the registration, which performs the deregisteration. 
    }

Here we register a callback method through CancellationToken to notify the task to wait thread, which can also be used in the way we often use WaitHandle.

    void Wait(WaitHandle wh, CancellationToken token)
    {
        (new[] { wh,  });
        if () //did cancellation wake us? 
            throw new OperationCanceledException(token);
    }

Advanced Applications

Since the examples are relatively simple, I will only list the code here and I will not introduce it more.

A CancellationToken corresponds to multiple tasks

    void Example4()
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        Func1();
        Func2();
        Func3();
        //... 
        (); // all listeners see the same cancellation request. 
    }

One task corresponds to multiple CancellationTokens

    void LinkingExample(CancellationToken ct1, CancellationToken ct2)
    {
        CancellationTokenSource linkedCTS =
        (ct1, ct2);
        try
        {
            SlowFunc();
        }
        catch (OperationCanceledException oce)
        {
            if ()
            {
                // ... 
            }
            else if ()
            {
                // ... 
            }
        }
        (); // clean up the linking. required. 
    }

Finally, let’s take another example of cancellation when concurrent query:

    private void RunQuery()
    {
        int[] data = { 1, 2, 3 };
        CancellationTokenSource cts = new CancellationTokenSource();
        var query = ()
                     .WithCancellation() // token given to library code 
                     .Select((x) => SlowFunc(x, )); // token passed to user code 
    }

    private int SlowFunc(int x, CancellationToken token) 
    { 
        int result 
        while(...) 
        { 
            if () 
            throw new OperationCanceledException(token); 
            ... 
        } 
        return result; 
    }

summary

The Cancellation Framework in .net 4.0 is still very practical. It can be more effectively simplified and standardized to use various cancellation operations. Since I am only aware of the superficiality, I will only introduce its basic usage here, and will continue to introduce it further in subsequent learning and application.

This is all about this article about .Net using Cancellation Framework to cancel parallel tasks. I hope it will be helpful to everyone's learning and I hope everyone will support me more.