使用 IsCancellationRequested 属性?

Sat*_*Sat 4 c# parallel-processing task-parallel-library

什么是使用CancellationTokenIsCancellationRequested财产?考虑下面的代码

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");
}
Run Code Online (Sandbox Code Playgroud)

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

svi*_*ick 7

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

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

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

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

一个问题是Wait()Task被取消的a 上执行 ing会引发异常,因此您必须捕获该异常。