将取消令牌传递给任务类构造函数有什么用

本文关键字:构造函数 什么 任务 取消 令牌传递 | 更新日期: 2023-09-27 18:36:10

下面是一个示例代码,用于创建一个模拟长时间运行的进程的新任务。这样的任务没有什么,纯粹专注于取消功能。我正在使用取消令牌来取消任务,代码对我来说效果很好。

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);

但是我无法理解的一件事是传递给Task构造函数的令牌参数(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;
       }
};

将取消令牌传递给任务类构造函数有什么用

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

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

  1. 如果令牌已取消在任务开始执行之前请求,任务不会执行。 它不会过渡到跑步,而是会立即过渡到"已取消"。 这避免了运行任务的成本,如果无论如何,它只会在运行时被取消。

  2. 如果身体的任务还监视取消令牌并抛出操作已取消包含该令牌的异常(这就是 ThrowIfCancellationRequested确实如此),然后当任务看到 OCE 时,它检查 OCE 的令牌是否与任务的令牌匹配。 如果它确实如此,该例外被视为对合作的承认取消,任务转换为"已取消"状态(而是比故障状态)。