【问题标题】:Should I use CancellationTokenSource or CancellationToken to Cancel a task in .NET我应该使用 CancellationTokenSource 还是 CancellationToken 来取消 .NET 中的任务
【发布时间】:2015-12-09 05:00:38
【问题描述】:

我看到CancellationTokenCancellationTokenSource 都有IsCancellationRequested getter 方法。大多数示例将CancellationToken 传递给在Task 内部执行的方法。在我看来,使用其中任何一个,调用都可以返回。如果我使用IsCancellationRequestedCancellationTokenSource,会不会有问题?我应该在什么时候抛出异常(通过使用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);
    }
}

【问题讨论】:

  • 仅当您希望它执行取消时才将方法传递给CancellationTokenSource。如果该方法是被取消的东西,请将其传递给CancellationToken

标签: c# task-parallel-library task


【解决方案1】:
  1. CancellationTokenSource 持有和控制CancellationToken 实例。任务方法应使用取消令牌但不修改它。如果您将CancellationTokenSource 传递给一个方法,该方法将完全控制取消令牌。所以方法应该以CancellationToken为参数。

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

【讨论】:

    【解决方案2】:

    在我看来,CancellationTokenSource 用于启动取消(例如,由另一个/父线程,)。 CancellationToken.Token 是关联的 CancellationToken,您可以将其传递给 TaskFactory.StartNew() as MSDN says

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

    然后Task 将监视CancellationToken.IsCancellationRequested 以确定何时关闭。

    对于财产CancellationToken.IsCancellationRequestedMSDN says

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

    总结一下,我想说CancellationTokenSource.IsCancellationRequested是用来关联CancellationTokenTaskFactory.StartNew()的。而CancellationToken.IsCancellationRequested 用于定义是否已针对此令牌请求取消。此外,IntelliSenseCancellationTokenSource.Token.IsCancellationRequestedCancellationToken.IsCancellationRequested 的定义相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-14
      • 2019-12-01
      相关资源
      最近更新 更多