我对取消多个任务感到困惑,并继续执行显示结果的任务。 根据我的理解,这个程序应该显示
任务已取消
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();
不幸的是它显示
完成任务
如果我取消注释取消例外的程序显示
任务已取消
完成任务
为什么呢?似乎我错过了一些东西,但我没看到......
答案 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}}之后,你的任务就差不多完成了。因此,任务中的任何内容都不会被取消,因此不会被标记为已取消。