Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are CancellationTokens guaranteed to be up-to-date?

Microsoft gives this example of CancellationToken use in .NET 4.

using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
    static void Main()
    {

        var tokenSource2 = new CancellationTokenSource();
        CancellationToken ct = tokenSource2.Token;

        var task = Task.Factory.StartNew(() =>
        {

            // Were we already canceled?
            ct.ThrowIfCancellationRequested();

            bool moreToDo = true;
            while (moreToDo)
            {
                // Poll on this property if you have to do
                // other cleanup before throwing.
                if (ct.IsCancellationRequested)
                {
                    // Clean up here, then...
                    ct.ThrowIfCancellationRequested();
                }

            }
        }, tokenSource2.Token); // Pass same token to StartNew.

        tokenSource2.Cancel();

        // Just continue on this thread, or Wait/WaitAll with try-catch:
        try
        {
            task.Wait();
        }
        catch (AggregateException e)
        {
            foreach (var v in e.InnerExceptions)
                Console.WriteLine(e.Message + " " + v.Message);
        }

        Console.ReadKey();
    }
}

However, my understanding is that if a variable is modified on one thread, another thread might not get the modified value, due to caching. And since the CancellationToken is cancelled on the main thread, how is the Task thread assured that the CancellationToken it is checking is actually up-to-date?

Why isn't it possible for the Task to be reading a cached value of the token?

Note: My motivation in asking this arises from wondering whether I need my CancellationToken instance variables to be volatile.

like image 443
Eric Avatar asked Aug 07 '12 16:08

Eric


People also ask

How does a CancellationToken work?

A CancellationToken enables cooperative cancellation between threads, thread pool work items, or Task objects. You create a cancellation token by instantiating a CancellationTokenSource object, which manages cancellation tokens retrieved from its CancellationTokenSource. Token property.

What is difference between CancellationTokenSource and CancellationToken?

CancellationTokenSource - This is the object responsible for creating a cancellation token and sending a cancellation request to all copies of that token. CancellationToken - This is the structure used by listeners to monitor the token's current state.

Should I dispose CancellationTokenSource?

Always call Dispose before you release your last reference to the CancellationTokenSource. Otherwise, the resources it is using will not be freed until the garbage collector calls the CancellationTokenSource object's Finalize method.

Which object do you inspect to determine if a long running task will be Cancelled?

The background long-running tasks are cancelled by using the CancellationToken object in Blazor.


1 Answers

This is handled internally within CancellationTokenSource. The private variable used to track the CTS's state is marked volatile, which prevents the internal state check from being stale.

My motivation in asking this arises from wondering whether I need my CancellationToken instance variables to be volatile.

You do not need to do this, as the checking is handled internally, and already handled properly for you.

Basically, when you create a CancellationToken from the CancellationTokenSource, the token contains a reference to the original source. This reference can never change, so the call to ThrowIfCancellationRequested checks the state of the source internally. Since the source state is itself volatile, it's never "stale" data.

like image 80
Reed Copsey Avatar answered Nov 09 '22 12:11

Reed Copsey