取消任务

Toa*_*yen 6 .net c# task-parallel-library

我尝试在取消下面的任务时运行一个简单的例子

CancellationTokenSource tokenSource2 = new CancellationTokenSource();

CancellationToken token2 = tokenSource2.Token;


Task task2 = new Task(() =>
{
    for (int i = 0; i < int.MaxValue; i++)
    {
        token2.ThrowIfCancellationRequested();
        Thread.Sleep(100);
        Console.WriteLine("Task 2 - Int value {0}", i);
    }
}, token2);

task2.Start();

Console.WriteLine("Press any key to cancel the task");
Console.ReadLine();

tokenSource2.Cancel();
Console.WriteLine("Task 2 cancelled? {0}", task2.IsCanceled);
Run Code Online (Sandbox Code Playgroud)

我预计 Console.WriteLine("Task 2 cancelled? {0}", task2.IsCanceled);会打印**"Task 2 cancelled? True"**,但它打印"假".

你知道发生了什么吗?这是预期的行为吗?谢谢.

编辑:确保在调用取消请求之前未完成任务.我加了Console.ReadLine().

svi*_*ick 5

首先,也许你误解了什么IsCanceled意思?这并不意味着"这Task是等待取消,所以它应该很快完成",这意味着"这Task已被取消,现在已经完成".

如果你没有误解,请考虑事件的顺序是什么.这是怎么回事:

  1. ThrowIfCancellationRequested() 被调用,但令牌尚未取消,所以它不会抛出.
  2. Thread.Sleep()被调用,所以线程运行Task睡眠.
  3. Cancel() 叫做.
  4. IsCanceled检查.该代码Task没有机会意识到令牌已被取消,所以它仍在运行,所以IsCanceled返回false.
  5. ThrowIfCancellationRequested()再次调用,这次它抛出,实际上取消了Task.

这就是ISCanceled回到false你身边的原因.如果你想要它返回true,你可以Thread.Sleep(150)在检查之前添加一些东西IsCanceled,或者更好的是,实际上等待Task完成.