c# - 使用 IsCancellationRequested 属性?

标签 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");
}

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

最佳答案

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

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

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

但这仍然不能完全修复您的程序。您需要告诉 Task 它已被取消。为此,您可以抛出包含 CancellationTokenOperationCanceledException(通常的做法是调用 ThrowIfCancellationRequested())。

其中的一个问题是 Wait() 处理一个被取消的 Task 会抛出一个异常,因此您必须捕获它。

关于c# - 使用 IsCancellationRequested 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15038529/

相关文章:

C# DataGridView 禁用列标题中的排序图标

matlab - Matlab中如何使用GPU的共享内存?

task-parallel-library - 将异步方法调用为同步时,Async CTP 和 Bcl.Async 之间的差异

c# - 将循环转换为任务

.net - Task.Delay 在 .NET 4 中没有记录吗?

c# - 如何使用 ASP.NET 和 C# 在 SQL Server 中保留换行符?

c# - 委托(delegate)的默认参数值

c# - 反序列化具有多个元素属性的 XML 文件 - 属性不反序列化

java - Java中子线程如何向主线程(方法)发送连续的消息?

c# - 多线程不处理所有任务