取消后直接调用 _cts.Dispose() 是否安全?
为了知道这一点,我们需要了解当我们取消 CancellationTokenSource 时会发生什么。
当您取消 CancellationTokenSource 时,它会继续调用通过 CancellationToken 注册的任何回调,该回调通过 CancellationToken.Register() 方法保存对其父源的引用。
当您处置 CTS 时,任何已注册的链接回调都会尝试从令牌中注销。如果它当前正在执行,它将等到它的委托完成。
这意味着,尽管您已处置 CTS,但它的对象仍被令牌引用。因此,它仍然不符合收集条件。
现在让我们看看CancellationToken.IsCancellationRequested:
public bool IsCancellationRequested
{
get
{
return m_source != null && m_source.IsCancellationRequested;
}
}
这意味着在处置时,检查取消将产生 true。这意味着,调用 dispose 后等待任务完成是安全的。
附带说明,如果您(出于某种原因)尝试通过已处置的CancellationTokenSource 传递令牌,您将遇到ObjectDisposedException。
编辑:
我想补充两点。首先,让我说我不建议使用这种方法。它应该适用于某些代码执行路径,但不适用于所有路径。 CancellationTokenSource 通常只有在你使用它的 WaitHandle 属性时才应该被释放。否则,最好让 GC 进行清理。但是,因为这是一个口味问题,你可以选择任何你喜欢的。我当然会建议您仅在您确定任务已观察到取消请求后才进行处理。
按照WaitHandle的用法,一旦你dispose它就会被dispose并清空,所以它不会被访问到。