在任务取消时处理 CancellationTokenSource 的代码是否正确?
Is code that disposes CancellationTokenSource while tasks are canceling correct?
我看到眼前这段代码,心存疑虑:
CancellationTokenSource _cts;
public void Dispose();
{
_cts.Cancel();
_cts.Dispose();
_task.Wait(); //wait for the task to be canceled!?
}
取消后直接调用 _cts.Dispose() 是否安全?是否会处理被取消任务所需的 CancellationTokenSource 基础资源以成功等待 CancellationToken(如果它想要这样做)?
Is it safe to call _cts.Dispose() straight after cancel?
为了知道这一点,我们需要了解取消 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
的用法,它会被释放并在你释放后被清空,所以它 将无法 访问。
我看到眼前这段代码,心存疑虑:
CancellationTokenSource _cts;
public void Dispose();
{
_cts.Cancel();
_cts.Dispose();
_task.Wait(); //wait for the task to be canceled!?
}
取消后直接调用 _cts.Dispose() 是否安全?是否会处理被取消任务所需的 CancellationTokenSource 基础资源以成功等待 CancellationToken(如果它想要这样做)?
Is it safe to call _cts.Dispose() straight after cancel?
为了知道这一点,我们需要了解取消 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
的用法,它会被释放并在你释放后被清空,所以它 将无法 访问。