是否有必要在处理之前取消取消

时间:2018-01-31 09:42:16

标签: c# memory cancellationtokensource

我大部分时间都在使用CancellationTokenSource进行超时。为了避免忘记dispose,当我完成CancellationTokenSource时,我使用了using语句。但在using声明结束之前,我总是在做CancellationTokenSource.Cancel()

如果没有使用取消,是否有必要在处理之前取消CancellationTokenSource

以下是我执行此操作的代码示例。

using (CancellationTokenSource TokenSource = new CancellationTokenSource(nTimeout * 1000))
{
  for (int i = 0; i < nLoop; i++)
  {
    if (TokenSource.Token.IsCancellationRequested)
    {
      bSuccess = false;
      break;
    }

    await Task.Delay(cDelay);
    // do some work
  }

  TokenSource.Cancel();
}

1 个答案:

答案 0 :(得分:2)

根据此来源处理CancellationTokenSource令牌后,可能会抛出ObjectDisposedException,因此您不应在处置完资源后使用CancellationTokenSource.Token。幸运的是,我没有在您的代码中看到这种情况。

当您取消CancellationTokenSource时,它会更改状态并通知已为该令牌注册的回调。但是,当您的代码即将使用令牌处理CancellationTokenSource时,您无需取消它。

所以在你的情况下,在处理之前没有必要取消CancellationTokenSource。但是,您的用例有点特殊。当你有后台任务时,你应该在处理源之前等待任务完成(如我的初始段落所述):

using (var cts = new CancellationTokenSource()) {
    var task = Task.Run(() => DoSomething(cts.Token));
    // Cancel cts or let it cancel itself based on a timeout.
    // Then wait for the task to end.
    await task;
}