C# 在任务取消时处理CancellationTokenSource的代码是否正确?
我看到前面的代码,我很怀疑:C# 在任务取消时处理CancellationTokenSource的代码是否正确?,c#,.net,cancellationtokensource,C#,.net,Cancellationtokensource,我看到前面的代码,我很怀疑: CancellationTokenSource _cts; public void Dispose(); { _cts.Cancel(); _cts.Dispose(); _task.Wait(); //wait for the task to be canceled!? } 取消后直接调用_cts.Dispose()安全吗?如果取消的任务想要成功地等待CancellationToken,那么它不会处理CancellationTokenS
CancellationTokenSource _cts;
public void Dispose();
{
_cts.Cancel();
_cts.Dispose();
_task.Wait(); //wait for the task to be canceled!?
}
取消后直接调用_cts.Dispose()安全吗?如果取消的任务想要成功地等待CancellationToken,那么它不会处理CancellationTokenSource的底层资源吗
取消后直接调用_cts.Dispose()安全吗
为了了解这一点,我们需要了解取消CancellationTokenSource
时会发生什么
当您取消CancellationTokenSource
时,它会继续调用通过CancellationToken
注册的任何回调,该回调通过CancellationToken.Register()
方法保存对其父源的引用
处置CTS时,将尝试从令牌中注销已注册的任何链接回调。如果它当前正在执行,它将等待直到它的委托完成
这意味着,尽管您已经处理了CTS,但它的对象仍然被令牌引用。因此,它仍然没有资格被收集
现在让我们看一下CancellationToken.IsCancellationRequested
:
public bool IsCancellationRequested
{
get
{
return m_source != null && m_source.IsCancellationRequested;
}
}
这意味着在处理时,检查取消将产生true。这意味着您可以在调用dispose后安全地等待任务完成
作为旁注,如果您(出于某种原因)试图通过令牌的disposedCancellationTokenSource
传递令牌,您将遇到一个ObjectDisposedException
编辑:
我想补充两件事。首先,我不建议使用这种方法。它应该适用于某些代码执行路径,但不适用于所有路径CancellationTokenSource
通常只有在您使用它的WaitHandle
属性时才应该被释放。否则,由GC来进行清洁是可以的。但是,因为这是一个口味的问题,你可以选择你喜欢的。我当然会建议,只有在您确定任务已遵守取消请求后,才进行处理
根据
WaitHandle
的用法,一旦您处理了它,它就会被处理并清空,因此它将无法访问。但是IsCancellationRequested不是唯一需要担心的场景,对吗?WaitHandle呢?WaitHandle
在dispose运行时将关闭。我不确定使用WaitHandle
是否是常见的用例。我会把它加到我的答案上。@Tim我在我的答案上加了一个重要的编辑。虽然你想做的是可能的,但我绝对不会推荐你。