为什么我的取消令牌没有终止这项工作?

Why isn't my cancellation token killing this job?

我相信我在下面创建并立即取消了一个任务。然而,当 运行 下面的代码时,您会注意到它永远旋转。是什么赋予了?为什么附加 src.Token 不会导致取消?

CancellationTokenSource src = new CancellationTokenSource();
Task t = Task.Run(()=> 
                  {
                      while (true) 
                      { 
                          Thread.Sleep(100); 
                      } 
                  },
                  src.Token);

Thread.Sleep(1000);
src.Cancel();
t.Wait();

在您的代码中 Task.Run 只有当令牌在任务执行开始之前被取消时才会被取消:

CancellationTokenSource src = new CancellationTokenSource();
src.Cancel();
Task t = Task.Run(()=> 
                  {
                      while (true) 
                      { 
                          Thread.Sleep(100); 
                      } 
                  },
                  src.Token);

Thread.Sleep(1000);
t.Wait();

您可以在 the official documentation

中阅读有关此案例的更多信息

另一种方法是将取消令牌传递给 Wait 方法:

CancellationTokenSource src = new CancellationTokenSource();
Task t = Task.Run(()=> {while (true) { Thread.Sleep(100); } },src.Token);
Thread.Sleep(1000);
src.Cancel();
t.Wait(src.Token);

在这种情况下,它的行为方式与 Task.Run 完全相同:"The wait terminates if a cancellation token is canceled before the task completes." (c) docs.microsoft.com

处理取消的正确方法是在长运行 任务的每次迭代中检查令牌状态:

CancellationTokenSource src = new CancellationTokenSource();
Task t = Task.Run(() =>
{
    while (true)
    {
        Thread.Sleep(100);
        src.Token.ThrowIfCancellationRequested();
    }
}, src.Token);
Thread.Sleep(1000);
src.Cancel();
t.Wait();