为什么我的取消令牌不能杀死这个工作?

时间:2019-08-05 22:00:31

标签: c# multithreading concurrency cancellation

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

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

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

1 个答案:

答案 0 :(得分:3)

在您的代码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完全相同:“如果在任务完成前取消了取消令牌,则等待会终止。” (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();