是否在任务取消正确时处理CancellationTokenSource的代码?
我在我面前看到这个代码,我很怀疑:
CancellationTokenSource _cts; public void Dispose(); { _cts.Cancel(); _cts.Dispose(); _task.Wait(); //wait for the task to be canceled!? }
取消后直接调用_cts.Dispose()是否安全? 如果想要这样做,是否会取消取消任务所需的CancellationTokenSource的底层资源以成功等待CancellationToken?
取消后直接调用_cts.Dispose()是否安全?
为了解这一点,我们需要了解取消CancellationTokenSource
时会发生什么。
当您取消CancellationTokenSource
,它会继续调用通过CancellationToken
注册的任何回调, CancellationToken
通过CancellationToken.Register()
方法保存对其父源的引用。
现在,当您处置CTS时,尝试从令牌取消注册已注册的任何链接回调。 如果它当前正在执行,它将等待它的委托完成。
这意味着,虽然你已经处理了你的CTS,它的对象仍然被令牌引用。 因此,它仍然没有资格收集。
现在让我们看一下CancellationToken.IsCancellationRequested
:
public bool IsCancellationRequested { get { return m_source != null && m_source.IsCancellationRequested; } }
这意味着在处理时,检查取消将产生真实。 这意味着,在调用dispose之后等待任务完成是安全的。
作为旁注,如果您(由于某种原因)尝试通过它的处置CancellationTokenSource传递令牌,您将遇到ObjectDisposedException
。
编辑:
我要添加两件事。 首先,我要说我不建议使用这种方法。 它应该适用于某些代码执行路径,但不适用于所有代码。 CancellationTokenSource
通常只有在您使用WaitHandle
属性时才会被处置。 否则,可以将其留在GC进行清洁。 但是,因为这是一个风味问题,你可以选择你喜欢的。 我肯定会建议您在确定任务已经遵守取消请求后才进行处置。
根据WaitHandle
使用情况,一旦你处理掉它就会被处理掉,因此它将无法访问。
- 在Windows C中将Windows窗体属性绑定到ApplicationSettings的最佳方法?
- 为什么BinaryWriter会在流的开头添加乱码? 你怎么避免它?
- System.Data.dll中出现“System.Data.SqlClient.SqlException”类型的exception
- 我应该在Reactive Extensions(Rx)Subject 上调用Dispose
- 示例:使用.NET / C中的委托加速Reflection API#
- HttpWebRequest中的“无法连接到远程服务器失败”
- 为什么十进制不是原始类型?
- 将WPF中的图像源绑定到URL
- C#中的struct v / s类 – 请解释一下这种行为