我应该在.NET中使用CancellationTokenSource还是CancellationToken来取消任务?

8

我看到 CancellationTokenCancellationTokenSource 都有 IsCancellationRequested 获取方法。大多数示例将 CancellationToken 传递给在 Task 中执行的方法。在我的理解中,使用其中任何一个,调用都可以返回。如果我使用 CancellationTokenSourceIsCancellationRequested,会有问题吗?何时应该抛出异常(使用 ThrowIfCancellationRequested),或者当有取消请求时只是从方法中返回,就像下面的代码一样?

class Program
{
    //If CancellationToken is passed then it behaves in same way?
    public static int TaskMethod(CancellationTokenSource tokenSource)
    {
        int tick = 0;
        while (!tokenSource.IsCancellationRequested)
        {
            Console.Write('*');
            Thread.Sleep(500);
            tick++;
            //token.Token.ThrowIfCancellationRequested();
        }
        //Should I just return or use ThrowIfCancellationRequested?
        return tick;
    }

    public static void Main()
    {
        CancellationTokenSource tokenSource = new CancellationTokenSource();
        CancellationToken token = tokenSource.Token;
        Task<int> task = Task.Factory.StartNew<int>(() => TaskMethod(tokenSource));
        Console.WriteLine("Press enter to stop the task");
        Console.ReadLine();
        tokenSource.Cancel();
        Console.WriteLine("{0}", task.Result);
    }
}

请阅读https://dev59.com/J2Yq5IYBdhLWcg3wxTWq。 - Janne Matikainen
9
只有当你希望方法执行取消操作时,才向其传递一个“CancellationTokenSource”。如果该方法是要被取消的对象,请传递一个“CancellationToken”。 - Phil K
2个回答

8
  1. CancellationTokenSource 持有并控制 CancellationToken 实例。任务方法应该使用取消标记,但不应修改它。如果您将 CancellationTokenSource 传递给一个方法,该方法将完全控制取消标记。因此该方法应该将 CancellationToken 作为参数。

  2. 在取消请求后,方法的行为由您决定。如果任务已被取消标记终止,没有规定任务应该处于取消状态(抛出 TaskCanceledException)。


1
在我看来,CancellationTokenSource 用于启动取消操作(例如通过另一个/父线程)。CancellationToken.Token 是相关联的 CancellationToken,您可以将其传递给类似于 TaskFactory.StartNew() 的东西 如 MSDN 所述

CancellationTokenSource.IsCancellationRequested 属性指示是否已为此令牌源请求取消,例如由于调用了其 Cancel 方法。

然后,Task 将监视 CancellationToken.IsCancellationRequested 以确定何时关闭。
对于属性 CancellationToken.IsCancellationRequested MSDN 说

获取是否已请求取消此令牌。

总之,我想说的是CancellationTokenSource.IsCancellationRequested用于将CancellationTokenTaskFactory.StartNew()相关联。而CancellationToken.IsCancellationRequested用于定义是否已为此令牌请求取消。此外,IntelliSense对于CancellationTokenSource.Token.IsCancellationRequestedCancellationToken.IsCancellationRequested具有相同的定义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接