如何保证取消令牌是最新的

本文关键字:最新 令牌 何保证 取消 | 更新日期: 2024-11-06 19:21:17

Microsoft给出了CancellationToken在.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();
    }
}

但是,我的理解是,如果一个变量在一个线程上被修改,另一个线程可能不会获得修改后的值,因为缓存。 由于主线程上的CancellationToken被取消,Task线程如何确保它正在检查CancellationToken实际上是最新的?

为什么Task无法读取令牌的缓存值?

注意:我问这个问题的动机源于想知道我是否需要volatile我的CancellationToken实例变量。

如何保证取消令牌是最新的

这是

CancellationTokenSource内部处理的。 用于跟踪 CTS 状态的私有变量标记为易失性,这可以防止内部状态检查过时。

问这个问题的动机源于想知道我是否需要我的 CancelToken 实例变量是可变的。

您不需要这样做,因为检查是在内部处理的,并且已经为您正确处理。

基本上,当您从CancellationTokenSource创建CancellationToken时,令牌包含对原始源的引用。 此引用永远不会更改,因此对 ThrowIfCancellationRequested 的调用会在内部检查源的状态。 由于源状态本身是volatile的,因此它永远不会是"过时"的数据。