繁体   English   中英

取消任务并继续

[英]Tasks cancellation and continue with

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

任务已取消

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

不幸的是它显示

任务完成

如果我取消注释取消异常,程序将显示

任务已取消

任务完成

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

在第一种情况下,这就是您的代码所说的-在请求取消时停止循环。 退出循环后,无需执行其他操作,因此任务已完成。

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

关于最后一部分,这是MSDN的摘录:

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

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

因此,即使已取消任务,该任务也已完成。

根据文档

Task.WhenAll

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

因此,确保您的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();时,您的任务几乎完成了cts.Cancel(); 在您将其称为任务之后。 因此,您的任务中没有任何内容被取消,因此未将其标记为已取消。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM