将CancellationToken传递给Task Class构造函数有什么用?

Pra*_*thy 20 .net c# multithreading cancellation-token

下面是一个示例代码,它创建一个模拟长时间运行进程的新任务.任务没有太多关于取消功能.我使用取消令牌来取消任务,代码对我来说很好.

       CancellationTokenSource CTS= new CancellationTokenSource();

       Task<Boolean> PTask = new Task<Boolean>(() => 
       {
           while (true)
           {
               if (!CTS.Token.IsCancellationRequested)
               {
                  Thread.Sleep(5000);
               }
               else{Console.WriteLine("Thread Cancelled");break;}
           }
           return true;

       }, CTS.Token, TaskCreationOptions.None);

       PTask.Start();
       Console.WriteLine("Hit Enter to cancel the Secondary thread you have started");
       Console.ReadLine();
       CTS.Cancel();
       System.Console.WriteLine(PTask.Result);

    }
}
Run Code Online (Sandbox Code Playgroud)

但是我无法理解的是将令牌参数(CTS.Token)传递给任务构造函数.传递参数的实际用途是什么,即使我没有将令牌传递给构造函数也可以实际取消任务.

下面是一个稍微修改过的版本,没有令牌参数.

      CancellationTokenSource CTS= new CancellationTokenSource();
      Task<Boolean> PTask = new Task<Boolean>(() => 
       {
           while (true)
           {
               if (!CTS.Token.IsCancellationRequested)
               {
                   Thread.Sleep(5000);
               }
               else
               {
                   Console.WriteLine("Thread Cancelled");
                   break;
               }
       };
Run Code Online (Sandbox Code Playgroud)

dar*_*yal 37

更新:以下msdn问题描述了原因:

将令牌传递到StartNew会将令牌与任务相关联.这有两个主要好处:

  1. 如果令牌在任务开始执行之前已请求取消,则任务将不会执行.它不会转换为Running,而是立即转换为Canceled.这样可以避免运行任务的成本,如果它在运行时只是被取消.

  2. 如果任务的主体也在监视取消令牌并抛出包含该令牌的OperationCanceledException(这是什么 ThrowIfCancellationRequested),那么当任务看到该OCE时,它会检查OCE的令牌是否与Task的令牌匹配.如果是,则该异常被视为对协作取消的确认,并且任务转换到已取消状态(而不是故障状态).