4

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块内的代码不会运行。如果是这样,轮询以查看是否请求取消有什么用?

4

1 回答 1

7

您的代码的问题是您不等待Task完成。所以,可能发生的事情是这样的:

  1. 你打电话Cancel()
  2. 你检查Status,它返回Running
  3. Task令人困惑的是,当仍在运行时,您会写“任务已完成” 。
  4. Main()完成,应用程序退出。
  5. (此时,IsCancellationRequested将从后台线程进行检查。但这永远不会发生,因为应用程序已经退出。)

要解决此问题,t.Wait()请在调用后添加Cancel()

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

一个问题是取消Wait()的 ingTask会引发异常,因此您必须抓住它。

于 2013-02-23T10:46:17.537 回答