关于.net:NET-CancellationTokenSource-取消任务用法详解

原文:https://docs.microsoft.com/en…

本文对原文进行了提炼并翻译为中文。

Cancel不代表终止代码

不要想当然地依附Cancel机制“terminate a Task”,这是做不到的!

一个常见的误会是勾销了一个工作后,该工作就会主动进行;但其实这种了解是不正确的;试想一下,如果勾销真的能够达到terminate一个Task的成果,那它和危险的Thread.Abort有什么区别呢?因为真的依照“cancel即在Task代码外部抛出异样”去了解,那么你没有对完结后的程序状态有任何开头工作。

所以CancellationTokenSource抑或其对应的CancellationToken都只是发一个告诉给Task:你能够完结了;而具体怎么捕捉这个音讯并响应,是Task的用户代码本人思考的问题。

参考原文中的代码,要害的一个片段是:

if (ct.IsCancellationRequested)
{
    Console.WriteLine("Task {0} cancelled", taskNum);
    ct.ThrowIfCancellationRequested();
}

这相似于软件工程中的“埋点”,即在要害的代码行中插入监控代码,判断工作是否被勾销

WhenAny或Wait(token)会导致异样抛出

看回原文中的代码:

try
{
    await Task.WhenAll(tasks.ToArray());
}
catch (OperationCanceledException)
{
    Console.WriteLine($"\n{nameof(OperationCanceledException)} thrown\n");
}

一旦工作勾销,那么Task.WhenAll会导致异样抛出;这里是非常容易误导人的一点:Task外部也产生了异样,从而打断的Task外部代码流,从而令工作强制退出了吗?

答案是:Task自身代码运行只受到本人外部代码管制,不可能单单因为CancellationTokenSource收回了勾销信号,就终端了工作的运行。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理