代码之家  ›  专栏  ›  技术社区  ›  Carbon

为什么我的取消代金券没有毁掉这份工作?

  •  0
  • Carbon  · 技术社区  · 5 年前

    我相信我创建并立即取消下面的任务。然而,当运行下面的代码时,您会注意到它会永远旋转。给什么?为什么不连接 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 回复  |  直到 5 年前
        1
  •  3
  •   Deleted    5 年前

    在你的代码中 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);
    

    在这种情况下,它的行为与 任务。运行 does:“如果取消令牌在任务完成之前被取消,则等待终止。”(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();