【问题标题】:Tasks cancellation and continue with任务取消并继续
【发布时间】:2016-11-28 14:35:36
【问题描述】:

我对取消几个任务感到困惑并继续执行一个任务以显示结果。 据我了解,这个程序应该显示

任务取消

CancellationTokenSource cts = new CancellationTokenSource();
List<Task> tasks = new List<Task>();
for(int i= 0; i<3; i++)
{
    tasks.Add(Task.Run(() =>{
        while(!cts.Token.IsCancellationRequested)
            Thread.Sleep(500);
    
        // Uncomment this to see 'Tasks canceled' in the result
        //if(cts.Token.IsCancellationRequested)
        //    cts.Token.ThrowIfCancellationRequested();
    },cts.Token));
}

Task.WhenAll(tasks).ContinueWith(task =>
{
    if(task.IsCanceled)
        Console.WriteLine("Tasks canceled");
    if(task.IsCompleted)
        Console.WriteLine("Tasks completed");
});
Thread.Sleep(2000);
cts.Cancel();

不幸的是它显示

任务完成

如果我取消注释程序显示的取消异常抛出

任务取消

任务完成

为什么?似乎我错过了什么,但我没有看到什么......

【问题讨论】:

  • 完成是真的,因为它结束了.. 不是因为它一直到最后没有问题
  • “取消”取消令牌不会自动取消任何任务。如果你不ThrowIfCancellationRequested,任务根本不会被取消,所以你看不到预期的输出。
  • 在此处查看对第二个已接受答案的第二条评论:stackoverflow.com/questions/7343211/…

标签: c# multithreading task


【解决方案1】:

在第一种情况下,这就是您的代码所说的 - 在请求取消时停止循环。在它退出循环后,没有什么可以执行,因此任务完成。

设计上要真正取消任务,你需要抛出异常来改变执行流程。实际上,您的代码示例中不需要 if 语句 - ThrowIfCancellationRequested 方法将自行处理此检查,如果已请求取消,则会抛出异常。

关于最后一部分,这里摘自 MSDN:

当任务处于三种最终状态之一时,IsCompleted 将返回 true:RanToCompletion、Faulted 或 Canceled。

https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.iscompleted(v=vs.110).aspx

所以任务就算被取消也是完成的。

【讨论】:

  • 好吧。但是为什么我必须抛出取消异常才能看到该任务被取消?
  • @Troopers 因为他们就是这样设计的。
【解决方案2】:

根据文档

Task.WhenAll

创建一个任务,该任务将在一个任务中的所有任务对象完成时完成 数组已完成。

所以保证你的 3 个任务全部结束后任务处于完整状态

你想要的大概是

Task.WhenAll(tasks).Wait();
Foreach(Task task in tasks)
{
    if(task.IsCanceled)
        Console.WriteLine("Tasks canceled");
    if(task.IsCompleted)
        Console.WriteLine("Tasks completed");
}

编辑:任务未取消的原因是因为您从未抛出该异常。让我们想象一下这种情况:当您调用cts.Cancel(); 时,您的任务几乎完成了,就在您调用它完成任务之后。因此,您的任务中没有任何内容被取消,因此它没有被标记为已取消。

【讨论】:

  • 问题是为什么任务没有被标记为已取消。当您等待任务时,它仍然可以被取消。
  • 对不起,你跑题了
猜你喜欢
  • 2012-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 2012-02-22
  • 1970-01-01
相关资源
最近更新 更多