任务取消并继续

时间:2016-11-28 14:35:36

标签: c# multithreading task

我对取消多个任务感到困惑,并继续执行显示结果的任务。 根据我的理解,这个程序应该显示

  

任务已取消

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();

不幸的是它显示

  

完成任务

如果我取消注释取消例外的程序显示

  

任务已取消

     

完成任务

为什么呢?似乎我错过了一些东西,但我没看到......

2 个答案:

答案 0 :(得分:1)

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

通过设计真正取消任务,您需要抛出异常以更改执行流程。实际上,代码示例中不需要if语句 - ThrowIfCancellationRequested方法将自行处理此检查,并在请求取消时抛出异常。

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

  

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

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

即使被取消,任务也完成了。

答案 1 :(得分:0)

基于doc

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

创建一个任务,该任务将在所有Task对象中完成   阵列已经完成。

因此任务保证在所有3个任务结束后处于完整状态

你想要的可能是

cts.Cancel();

编辑:未取消任务的原因是因为您从未抛出该异常。让我们想象一下这种情况:当你打电话给{{1}}之后,你的任务就差不多完成了。因此,任务中的任何内容都不会被取消,因此不会被标记为已取消。