第三方物流的任务;t检查它是否';s已取消,仍将取消
本文关键字:取消 任务 第三方 检查 是否 | 更新日期: 2023-09-27 17:59:49
我认为CancellationToken/CancellationTokenSource系统的工作方式有点像C++volatile bool bFlagCancelled
,这意味着任务的取消是自愿的,它依赖于任务本身来不时检查它是否被取消并抛出异常,无论是显式的还是通过调用ThrowIfCancellationRequested()
。
但是,如果在StartNew()
之后立即调用Cancel,则任务将停止,并且调用Wait()
将抛出一个TaskCanceledException
。
例如,对于此代码:
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
Task task = Task.Factory.StartNew(
() =>
{
Console.WriteLine("start sleep");
Thread.Sleep(1000);
Console.WriteLine("sleep ended");
}
, token);
// Thread.Sleep(1);
source.Cancel();
Console.WriteLine("start wait");
task.Wait();
Console.WriteLine("wait ended");
我得到这个输出:
开始等待异常:System.AggregateException:出现一个或多个错误。--->System.Threading.Tasks.TaskCanceledException:任务已取消
但是,如果我取消对// Thread.Sleep(1);
的注释,那么行为就会发生变化,我会得到以下输出:
开始睡眠开始等待睡眠结束等待结束
现在我想这可能是因为task.Start()
还没有被调用,但据我所知,StartNew()
在返回之前会调用task.Start()
——这就是为什么它没有同步成本,建议与创建new Task
并自己调用task.Start()
相比。
因此,这意味着在某些情况下,即使不检查取消令牌,任务也会自动取消。这是唯一发生这种情况的情况,还是有更多的情况发生这种情况?
Task.Factory.StartNew
在返回之前安排任务,但这并不意味着任务实际上已经开始执行。因此,如果TaskScheduler
接受该任务,则仍有取消该任务的空间(内部调用TaskScheduler.TryDequeue
方法。如果返回true,则该任务可以标记为已取消)。