使用IsCancellationRequested属性?

时间:2013-02-23 08:09:57

标签: c# parallel-processing task-parallel-library

CancellationToken IsCancellationRequested属性的用途是什么?请考虑以下代码

static void Main(string[] args)
{
    CancellationTokenSource tokenSource = new CancellationTokenSource();
    var token = tokenSource.Token;
    Console.WriteLine("Press Enter to Start.\nAgain Press enter to finish.");
    Console.ReadLine();
    Task t = new Task(() =>
    {
        int i = 0;
        while (true)
        {
            if (token.IsCancellationRequested)
            {
                Console.WriteLine("Task Cancel requested");
                break;
            }
            Console.WriteLine(i++);
        }
    }, token);

    t.Start();

    // wait for input before exiting
    Console.ReadLine();
    tokenSource.Cancel();
    if(t.Status==TaskStatus.Canceled)
        Console.WriteLine("Task was cancelled");
    else
        Console.WriteLine("Task completed");
}

我发现在极少数情况下if块内的代码不会运行。如果是这样,有什么用轮询来查看是否要求取消?

1 个答案:

答案 0 :(得分:3)

您的代码存在的问题是您不必等待Task完成。那么,会发生什么:

  1. 您致电Cancel()
  2. 您选中Status,返回Running
  3. 令人困惑的是,当Task仍在运行时,您写了“任务已完成”。
  4. Main()完成,应用程序退出。
  5. (此时,将从后台线程检查IsCancellationRequested。但这种情况从未发生过,因为应用程序已经退出。)
  6. 要解决此问题,请在致电t.Wait()后添加Cancel()

    但是仍然无法完全修复你的程序。您需要告诉Task它已被取消。你通过抛出包含OperationCanceledException的{​​{1}}来做到这一点(通常的方法就是调用CancellationToken)。

    有一个问题是ThrowIfCancellationRequested()被取消的Wait()会引发异常,所以你必须抓住它。