【问题标题】:Can cancellation token be used at tasks method within?可以在任务方法中使用取消令牌吗?
【发布时间】:2016-01-08 05:55:51
【问题描述】:

我刚刚开始处理任务,但对于在任务中调用方法,我遇到了一些我不太了解的事情。我已经开始了这样的新任务:

var ts = new CancellationTokenSource();
var token = ts.Token;

Task.Run(() => Control(), token);


void Control() 
{
     while(!token.IsCancellationRequested) 
     {
          token.ThrowIfCancellationRequested();

          switch(ENUM) 
          {

               case SOMETHING:

                 StartSomething();
               break;

          }


          Task.Delay(50, token).wait();
     }
 }

现在我不明白StartSomething() 在令牌被取消后的行为。如果StartSomething() 也包含一个while 循环,我也可以使用吗?

!token.IsCancellationRequested

token.ThrowIfCancellationRequested();

同样,如果在 StartSomething() 循环中抛出了 Cancellation 异常,它会立即取消任务吗?

【问题讨论】:

  • 理想情况下,您希望将token 传递给任何可能需要一些时间的东西,可能是StartSomething(),并定期检查令牌是否取消。
  • 谢谢!如果任务在 StartSomething() 方法中被取消,是立即取消任务,还是先返回 Control() 循环再执行?
  • @user2818626 它会抛出一个异常,该异常会通过Control 冒泡。只要你没有抓住它,任务就会被取消。
  • @user2818626 是的,是的。异步几乎总是比同步阻塞好。
  • @user2818626 这就是 await 的作用。它等待,只是异步的。该行之后的代码将不会继续运行。

标签: c# .net task-parallel-library task


【解决方案1】:

是的,您可以轻松地将相同的令牌传递给StartSomething,其中的异常将冒泡到Control 并取消任务。如果您不这样做,那么即使 CancellationTokenwas cancelled until it returns control toControl` 观察到令牌,它也会继续运行:

void StartSomething(CancellationToken token)
{
    while (true)
    {
        token.ThrowIfCancellationRequested(); // Will cancel the task.
        // ...
    }
}

请记住,token.ThrowIfCancellationRequested() 将引发异常并且任务将被取消,而 !token.IsCancellationRequested 将简单地完成任务而不将其标记为已取消。

【讨论】:

  • 谢谢!现在一切都说得通了:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多